-2

To permanently update ~/.profile with source, only working on manual input. Also reboot of the whole system won‘t update ~/.profile and i need to update it manual.

Is there a special code style to use it as working code inside a bash/shell script or is this special code not intended to be used in automated scripts?

Need it to automate installation of golang.

In the following code the line "source ~/.profile" won't work, and without any error messages, the rest is working fine:

#!/bin/bash
sudo apt update
sudo apt -y upgrade
cd ~
curl -O https://dl.google.com/go/go1.12.5.linux-amd64.tar.gz
tar xvf go1.12.5.linux-amd64.tar.gz
sudo chown -R root:root ./go
sudo mv go /usr/local
cd ~
sudo rm go1.12.5.linux-amd64.tar.gz
sudo echo "export GOPATH=\$HOME/work" >> ~/.profile
sudo echo "export PATH=\$PATH:/usr/local/go/bin:\$GOPATH/bin" >> ~/.profile
source ~/.profile
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • If by "manual input" you mean entry *at an interactive shell*, then the problem is that sourcing the file sets variables/aliases/etc. *inside the shell that does the sourcing*, and the shell running your script is different from the user's interactive interpreter. If instead by "not working" you mean that you get an error like `source: command not found`, that means you're using `sh` when you should be using `bash`. If instead by "not working" you mean that aliases aren't set, that's because aliases are off-by-default in interactive interpreters. – Charles Duffy May 24 '19 at 12:34
  • However, the very fact that we need to guess which of many possible interpretations you mean means that this isn't a question sufficiently well-specified as to be answerable. – Charles Duffy May 24 '19 at 12:34
  • Thank you for your reply. I updated the question with to whole script. Execution of the last line won't work, without any errors. Seems it works, but, command "go version" or even "go" won't be recognized. At this point, golang won't work. I need to open a terminal by myself and tipe in "source ~/.profile" to work permanently. – Tobias O.R. Alke May 24 '19 at 12:48
  • Right -- `source` runs something *in the shell that you're actively running*. In a script, that's the shell that runs the script, **not** the shell the user started the script from. So `source ~/.bashrc` in that context will change the `GOPATH` **for the script itself**, but not for the user who started the script... and since you're doing that right before the script exits, changing anything in the script's own environment is not very useful. – Charles Duffy May 24 '19 at 13:11
  • I'm voting to reopen this question since I would post the following as an answer which is different to the one in the linked question and specific to this one. Use `exec bash` or something similar instead of `source ~/.profile` - this replaces the currently running Bash with another instance which will itself load the new `.profile`. Or source the script itself rather than running it - then the commands in the script are run in the _current_ shell, _including_ the `source ~/.profile`. – Dennis Williamson May 24 '19 at 16:25
  • 1
    Why would you `sudo echo` a string? Usually `echo` doesn't need any particular privileges. You also don't need `sudo` to remove a file you downloaded as yourself a few commands back. – tripleee May 24 '19 at 16:42

2 Answers2

1

Preferred:

Source the script itself rather than running it - then the commands in the script are run in the current shell, including the source ~/.profile.

Alternative (since this replaces the running shell, history, variable values, and other state will be lost. So there should be a very good reason to use this method):

Use exec bash or something similar instead of source ~/.profile - this replaces the currently running Bash with another instance which will itself load the new .profile.

Dennis Williamson
  • 346,391
  • 90
  • 374
  • 439
  • 2
    Given as this discards all the other state in the OP's original shell, it's a very big hammer. I would be very surprised and dismayed if running some random program left me in a new interactive shell that didn't have any functions/variables/etc active except those defined in my dotfiles. – Charles Duffy May 24 '19 at 16:54
  • @CharlesDuffy: True. I'll note that in my answer. – Dennis Williamson May 24 '19 at 16:56
0

Here is a refactoring which defers the decision to the user and cleans up the script somewhat.

#!/bin/bash
# Put this in a variable so there is only one place to update
tarball='go1.12.5.linux-amd64.tar.gz'
sudo apt update
sudo apt -y upgrade
# cd || why would you?
curl -O "https://dl.google.com/go/$tarball"
tar xvf "$tarball"
sudo chown -R root:root ./go
sudo mv go /usr/local
rm "$tarball"
printf '%s\n' "export GOPATH=\$HOME/work" \
       "export PATH=\$PATH:/usr/local/go/bin:\$GOPATH/bin" >> ~/.profile
echo "$0: done. source ~/.profile or exec bash to activate new settings." >&2
tripleee
  • 175,061
  • 34
  • 275
  • 318
  • Actually isn't the recommendation to use `apt-get` over `apt` in scripts still? – tripleee May 24 '19 at 18:09
  • Thank's for refinement, it's prefereable, but didn't solve the problem. Even if i start a new terminal, or reboot the whole computer after executing the installation script, golang won't be recognized until i manually type in "source ~/.profile" - The other suggestions i need to think about. My skills in bash/shell scripts are currently not so deep. – Tobias O.R. Alke May 24 '19 at 19:23
  • Your Bash configuration is hosed in other interesting ways if it doesn't read `.profile` when you log in. – tripleee May 25 '19 at 03:31