Expecting to Change Exported Variables

Problem

A common beginner mistake is to treat exported shell variables like globals in a programming environment. But exported variables are only one way: they are included in the environment of the invoked shell script, but if you change their values, those changes are not seen by the calling script.

Here is the first of two scripts. This one will set a value, invoke a second script, and then display the value after the second script completes, so as to see what (if anything) has changed:

$ cat first.sh
#
# a simple example of a common mistake
#
# set the value:
export VAL=5
printf "VAL=%d\n" $VAL
# invoke our other script:
./second.sh
#
# now see what changed (hint: nothing!)
printf "%b" "back in first\n"
printf "VAL=%d\n" $VAL
$

The second script messes with a variable named $VAL, too:

$ cat second.sh
printf "%b" "in second\n"
printf "initially VAL=%d\n" $VAL
VAL=12
printf "changed so VAL=%d\n" $VAL
$

When we run the first script (which invokes the second one, too) here’s what we get:

$ ./first.sh
VAL=5
in second
initially VAL=5
changed so VAL=10
back in first
VAL=5
$

Solution

The old joke goes something like this:

Patient: “Doctor, it hurts when I do this.”
Doctor: “Then don’t do that.”

The solution here is going to sound like the doctor’s advice: don’t do that. You will have to structure your shell scripts so that such a hand-off is not necessary. One way to do that is by explicitly echoing the results of the second script so that the first script ...

Get bash Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.