Skip to main content
the modified value should be visible here, though
Source Link
ilkkachu
  • 147.8k
  • 16
  • 268
  • 441

"Variables present in the shell’s initial environment are automatically exported to child processes. The Bourne shell does not normally do this unless the variables are explicitly marked using the export command.".

Consider:

% export FOO=abc
% bash -c 'FOO=xyz; echo "bash: FOO=$FOO"; echo "env:"; env |grep FOO'
bash: FOO=xyz
env:
FOO=xyz

Here, I've set FOO in my interactive shell (zsh, but it doesn't matter), and set it as exported. Then I run Bash, which receives that variable in its environment, changes its value, prints it, and then runs env. That's an external command, so it only sees variables that inner Bash explicitly passes to it. We see the modified value of FOO is visible in the inner Bash, and in env, so Bash indeed imported the variable from its environment, and passed it on as it would pass any exported variable.

The other behaviour the quote seems to describe would be that the inner shell would not pass the variable on to env, and you'd see something like this instead:

bash: FOO=barFOO=xyz
env:

I don't know what the actual behaviour with all historical implementations has been, all I could reproduce was this with heirloom-sh (the same behavior as Kusalananda mentioned), only the original value of the variable is passed on:

% ./heirloom-sh -c 'FOO=xyz; echo "sh: FOO=$FOO"; echo "env:"; env |grep FOO'
sh: FOO=xyz
env:
FOO=abc

An explicit export FOO inner shell would have the current value also passed on. Here, the shell does make the original value of FOO visible to the script, so echo "FOO=$FOO" as the first thing would also print FOO=abc.

"Variables present in the shell’s initial environment are automatically exported to child processes. The Bourne shell does not normally do this unless the variables are explicitly marked using the export command.".

Consider:

% export FOO=abc
% bash -c 'FOO=xyz; echo "bash: FOO=$FOO"; echo "env:"; env |grep FOO'
bash: FOO=xyz
env:
FOO=xyz

Here, I've set FOO in my interactive shell (zsh, but it doesn't matter), and set it as exported. Then I run Bash, which receives that variable in its environment, changes its value, prints it, and then runs env. That's an external command, so it only sees variables that inner Bash explicitly passes to it. We see the modified value of FOO is visible in the inner Bash, and in env, so Bash indeed imported the variable from its environment, and passed it on as it would pass any exported variable.

The other behaviour the quote seems to describe would be that the inner shell would not pass the variable on to env, and you'd see something like this instead:

bash: FOO=bar
env:

I don't know what the actual behaviour with all historical implementations has been, all I could reproduce was this with heirloom-sh (the same as Kusalananda mentioned), only the original value of the variable is passed on:

% ./heirloom-sh -c 'FOO=xyz; echo "sh: FOO=$FOO"; echo "env:"; env |grep FOO'
sh: FOO=xyz
env:
FOO=abc

An explicit export FOO inner shell would have the current value also passed on. Here, the shell does make the original value of FOO visible to the script, so echo "FOO=$FOO" as the first thing would also print FOO=abc.

"Variables present in the shell’s initial environment are automatically exported to child processes. The Bourne shell does not normally do this unless the variables are explicitly marked using the export command.".

Consider:

% export FOO=abc
% bash -c 'FOO=xyz; echo "bash: FOO=$FOO"; echo "env:"; env |grep FOO'
bash: FOO=xyz
env:
FOO=xyz

Here, I've set FOO in my interactive shell (zsh, but it doesn't matter), and set it as exported. Then I run Bash, which receives that variable in its environment, changes its value, prints it, and then runs env. That's an external command, so it only sees variables that inner Bash explicitly passes to it. We see the modified value of FOO is visible in the inner Bash, and in env, so Bash indeed imported the variable from its environment, and passed it on as it would pass any exported variable.

The other behaviour the quote seems to describe would be that the inner shell would not pass the variable on to env, and you'd see something like this instead:

bash: FOO=xyz
env:

I don't know what the actual behaviour with all historical implementations has been, all I could reproduce was this with heirloom-sh (the same behavior as Kusalananda mentioned), only the original value of the variable is passed on:

% ./heirloom-sh -c 'FOO=xyz; echo "sh: FOO=$FOO"; echo "env:"; env |grep FOO'
sh: FOO=xyz
env:
FOO=abc

An explicit export FOO inner shell would have the current value also passed on. Here, the shell does make the original value of FOO visible to the script, so echo "FOO=$FOO" as the first thing would also print FOO=abc.

Source Link
ilkkachu
  • 147.8k
  • 16
  • 268
  • 441

"Variables present in the shell’s initial environment are automatically exported to child processes. The Bourne shell does not normally do this unless the variables are explicitly marked using the export command.".

Consider:

% export FOO=abc
% bash -c 'FOO=xyz; echo "bash: FOO=$FOO"; echo "env:"; env |grep FOO'
bash: FOO=xyz
env:
FOO=xyz

Here, I've set FOO in my interactive shell (zsh, but it doesn't matter), and set it as exported. Then I run Bash, which receives that variable in its environment, changes its value, prints it, and then runs env. That's an external command, so it only sees variables that inner Bash explicitly passes to it. We see the modified value of FOO is visible in the inner Bash, and in env, so Bash indeed imported the variable from its environment, and passed it on as it would pass any exported variable.

The other behaviour the quote seems to describe would be that the inner shell would not pass the variable on to env, and you'd see something like this instead:

bash: FOO=bar
env:

I don't know what the actual behaviour with all historical implementations has been, all I could reproduce was this with heirloom-sh (the same as Kusalananda mentioned), only the original value of the variable is passed on:

% ./heirloom-sh -c 'FOO=xyz; echo "sh: FOO=$FOO"; echo "env:"; env |grep FOO'
sh: FOO=xyz
env:
FOO=abc

An explicit export FOO inner shell would have the current value also passed on. Here, the shell does make the original value of FOO visible to the script, so echo "FOO=$FOO" as the first thing would also print FOO=abc.