Unix & Linux
bash shell environment-variables
Updated Fri, 20 May 2022 22:11:46 GMT

Why does FOO=bar; export the variable into my environment


If I run

FOO=bar docker run -it -e FOO=$FOO debian env

That environment variable is not set in the command output for the env command.

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=03f3b59c0aab
TERM=xterm
FOO=
HOME=/root

But if I run

FOO=bar; docker run -i -t --rm -e FOO=$FOO debian:stable-slim env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=672bfdcde93c
TERM=xterm
FOO=bar
HOME=/root

Then the variable is available from the container and also exported into my current shell environment.

echo $FOO
bar

I expect this behavior with export FOO=bar but why does that happen with ; too?




Solution

No, FOO=bar; does not export the variable into my environment

A var is set in the (present) environment only if it was previously exported:

$ export foo
$ foo=bar
$ env | grep foo
foo=bar

A variable is set in the environment of a command when it is placed before the command. Like foo=bar command. And it only exists while the command runs.

$ foo=bar bash -c 'echo "foo is = $foo"'
foo is = bar

The var is not set for the command line (in the present shell):

$ foo=bar bash -c echo\ $foo

Above, the value of $foo is replaced with nothing by the present running shell, thus: no output.

Your command:

$ FOO=bar docker run -it -e FOO=$FOO debian env

is converted to the actual string:

$ FOO=bar docker run -it -e FOO= debian env

by the present running shell.

If, instead, you set the variable (in the present running shell) with foo=bar before running the command, the line will be converted to:

$ FOO=bar; docker run -it -e FOO=bar debian env

A variable set to the environment of a command is erased when the command returns:

$ foo=bar bash -c 'echo'; echo "foo was erased: \"$foo\""

Except when the command is a builtin in some conditions/shells:

$ ksh -c 'foo=bar typeset baz=quuz; echo $foo'
bar




Comments (3)

  • +2 – The variable FOO is also not exported to the current shell environment, but set as a shell variable, unless it has been previously exported. — May 20, 2019 at 21:01  
  • +0 – Not knowing anything about Docker, I wonder if it would actually work if the -e FOO=$FOO thing (which I presume is used to set an environment variable) is removed since FOO is set in Docker's environment. — May 20, 2019 at 21:03  
  • +0 – Sorry, I should have posted this as a comment to the question, where Rothgar said that FOO was also "exported into my current shell environment." — May 21, 2019 at 03:58