Bash – How to pass environment variables to a non-interactive shell (with example)

bashenvironment-variablesscripting

In a sh script another sh script is started with su -l <user> -c /path/to/script.sh. As far as I understood script.sh will be run in a non-interactive shell. The official documentation tries to explain how to set variables in such a non-interactive shell, namely pass them in BASH_ENV[http://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html ]. This is obviously an insufficient explanation for a beginner and there's no (real) example (didn't find one in $SEARCH_ENGINE neither).

if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi

can mean mean a lot [1]. Can someone please give an example of an environment variable passed to a non-interactive shell.

Just to make sure: the difference between login and non-login as well as interactive and non-interactive are clear for me (https://superuser.com/questions/636219/where-should-i-export-an-environment-variable-so-that-all-combinations-of-bash-d or referenced link if anyone is interested).


[1]I tried

  • BASH_ENV="\\$PATH=$PATH\\n\\$JAVA_HOME=$JAVA_HOME" su -l artifactory -c echo $JAVA_HOME
  • BASH_ENV="\$PATH=$PATH\n\$JAVA_HOME=$JAVA_HOME" su -l artifactory -c echo $JAVA_HOME
  • su -l artifactory -c echo $JAVA_HOME

Best Answer

If it is an sh script - as in, it explicitly references #!/bin/sh - which might still be bash but would be like invoking it with --posix --no-rc --no-profile - then you can specify the ENV file with the ENV environment variable:

ENV=/path/to/rcfile sh

Specific variables need either to be declared on the command-line - as above for $ENV - or else with export. For example, for $PATH you do:

export "PATH=$PATH:/some/more/paths"; sh

The $BASH_ENV variable you reference is not a file you need to source - and it isn't interpreted anyway when bash is invoked as sh - but is rather a path to a file that is sourced when a non-interactive bash shell is invoked - such as with a script that specifies the:

#!/bin/bash

...or whatever bang line.

Another way you might like to invoke your script/shell is with the env utility. It can be used to explicitly remove values from the environment, or else, as is usually easiest, to wipe it clean from the start:

env - BASH_ENV=/path/to/rcfile /usr/bin/bash /some/script/file

That will tell env to invoke the /usr/bin/bash command - with all its arguments appended - with the $BASH_ENV environment variable specified, but otherwise with a clean environment entirely.

Related Question