如果我跑
FOO=bar docker run -it -e FOO=$FOO debian env
该命令的命令输出中未设置该环境变量env
。
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=03f3b59c0aab
TERM=xterm
FOO=
HOME=/root
但如果我跑
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
然后该变量可以从容器中获取,并且还可以导出到我当前的 shell 环境中。
echo $FOO
bar
我预计会出现这种行为,export FOO=bar
但为什么也会发生这种情况;
?
答案1
不,FOO=酒吧;才不是将变量导出到我的环境中
仅当先前导出了 var 时,才会在(当前)环境中设置 var:
$ export foo
$ foo=bar
$ env | grep foo
foo=bar
当变量放置在命令之前时,变量就被设置在命令的环境中。喜欢foo=bar command
。它仅在命令运行时存在。
$ foo=bar bash -c 'echo "foo is = $foo"'
foo is = bar
没有为命令行设置 var(在当前 shell 中):
$ foo=bar bash -c echo\ $foo
上面, 的值$foo
被替换为当前正在运行的 shell,因此:没有输出。
您的命令:
$ FOO=bar docker run -it -e FOO=$FOO debian env
转换为实际字符串:
$ FOO=bar docker run -it -e FOO= debian env
通过当前正在运行的 shell。
相反,如果您在运行命令之前设置变量(在当前运行的 shell 中)foo=bar
,则该行将转换为:
$ FOO=bar; docker run -it -e FOO=bar debian env
当命令返回时,设置为命令环境的变量将被删除:
$ foo=bar bash -c 'echo'; echo "foo was erased: \"$foo\""
除了当命令在某些条件/shell 中是内置命令时:
$ ksh -c 'foo=bar typeset baz=quuz; echo $foo'
bar
答案2
有许多变体需要考虑:
只需创建一个名为value 的
FOO=bar
变量,但该变量不会传递到新进程:FOO
bar
$ echo $FOO $ FOO=bar $ echo $FOO bar $ bash # Start a new bash process $ echo $FOO # Variable is not set in the new process $ exit # Exit new bash process
运行
FOO=bar <command>
将使用变量集运行给定的命令(但不影响原始 shell 的环境):$ echo $foo $ FOO=baz bash # start a new bash process $ echo $FOO baz $ exit # exit the new bash process exit $ echo $FOO # No FOO in the original bash process $
做
FOO=foo; <command>
相当于(1);在两个命令之间添加分号相当于在两个单独的行上运行这两个命令:$ FOO=foo; echo $FOO foo $ bash $ echo $FOO $ exit exit $ echo $FOO foo $
使用
export
会将 shell 环境中的变量传递给新创建的进程:$ export FOO=bar $ echo $FOO # Value set in original shell bar $ bash # Start another shell $ echo $FOO bar # Value was passed along to new process $ exit exit
答案3
FOO=bar docker run -it -e FOO=$FOO debian env
这里$FOO
fromFOO=$FOO
将被扩展前分配FOO=bar
发生。
您可以通过一个更直接的示例来检查这一点:
FOO=first
FOO=second echo FOO=$FOO
=> FOO=first
FOO=third; echo FOO=$FOO
=> FOO=third
表单确实会在 的环境中FOO=bar cmd
设置,但是像这样的命令不会自动导出它的FOO=bar
cmd
docker
自己的环境到容器中,但环境变量必须使用开关显式添加-e
。
同样,更简单的演示是:
FOO=before
FOO=after env - FOO=$FOO printenv FOO
=> before