bashshell

How to run a shell script from a shell script so that previously exported variables are not available?


Scenario:

$ cat t42.sh
source t42a.sh
bash t42b.sh

$ cat t42a.sh
export x="y"

$ cat t42b.sh
echo $x

$ bash t42.sh
y

I need to somehow run t42b.sh from t42.sh in a "clean environment", so that x is not available in t42b.sh.

Is this possible at all (w/o unset / export -n)? If so, then how?


Solution

  • I need to somehow run t42b.sh from t42.sh so that x is not available in t42b.sh.

    Is this possible at all (w/o unset / export -n)? If so, then how?

    Yes, you can do this without modifying the environment from which t42b.sh is launched. There are several ways, but one of the easier and more portable is to run t42b.sh via the env command:

    env — set the environment for command invocation

    Your most portable option with env is to start with an empty environment and add the environment variables that the script you are launching should have (warning: there may be more of these than you think). This would be something like:

    env -i PATH=$PATH USER=$USER HOME=$HOME t42b.sh
    

    With GNU env, however, and maybe others, you also have the alternative of using env to unset specific variables for the command to be launched, maybe something like this:

    env -u x t42b.sh
    

    If it would be satisfactory for x to be defined to a null value in t42b.sh, as opposed to being undefined altogether, then there's an easier way: just define it to nothing on t42b.sh's command line:

    x= t42b.sh
    
    # or, equivalently:
    
    x='' t42b.sh