I have a bash script script.sh which contains the following line:

sudo -u myusername sh ~/.profile

From a shell I am able to just call source ~/.profile but that does not work in a script and this command does. It forces my current shell to read my ~/.profile

However, my ~/.profile contains the following lines:

if [ -f ~/.bashrc ]; then
    source ~/.bashrc

As it is supposed to source my ~/.bashrc. But, when I run script.sh I get the following error:

/home/username/.profile: 24: /home/username/.profile: source: not found

Is it possible to source my ~/.bashrc file from my ~/.profile (which is itself being called from another script) without changing either my ~/.bashrc or my ~/.profile?

This script.sh downloads my ~/.profile and ~/.bashrc file and puts them in the right place, so I want to source those files from within script.sh once they are downloaded and have them affect the shell session which I used to run script.sh

  • Why do you run a bash script with sh? – Kusalananda Apr 15 '18 at 9:08
  • Also, running the ~/.profile file won't set any of the environment variables for the current shell, especially not when run with sudo. You will have to source the file. Please describe what it is you want to achieve. – Kusalananda Apr 15 '18 at 9:15

The error comes from trying to execute the ~/.profile file with sh, which does not understand source (sh uses . (dot) instead, which also works in bash and all other POSIX shells).

Furthermore, executing ~/.profile will not set the environment variables that this file sets in the shell that executes it. This is because it runs in its own subshell.

A child shell (which is what you get when you execute ~/.profile rather than sourcing it) will never affect the environment of the parent shell (the shell that you execute the script from). You can therefore not set variables in ~/.profile and expect them to then be set in your script unless you source the file.

Running sudo source ~/.profile will not help here as sudo will be a child process of the current shell.

Related, extra information:

To set up the environment for a script that is not run from an interactive shell (where ~/.profile and ~/.bashrc are already sourced), set the BASH_ENV variable to the appropriate file upon invoking the script. This will make bash source the $BASH_ENV file before handing control over to your script.

For example:

BASH_ENV="$HOME/.profile" "$HOME/scripts/myscript.sh"

This is only necessary if invoking the script from a non-interactive shell session, such as a cron job, and if you need to access environment variables set up in ~/.profile or any file that ~/.profile sources.

From an interactive shell session, the BASH_ENV variable does not have to be set in this way, and the script does not need to source ~/.bashrc nor ~/.profile since these have already been sourced.

  • I updated my question. Those files do not exist prior to me running script.sh - will this still work? – Startec Apr 15 '18 at 9:31
  • @Startec No, the file has to exist. The main error is that you are trying to execute a script written for bash with sh though. – Kusalananda Apr 15 '18 at 9:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.