为什么 FOO=bar;将变量导出到我的环境中

为什么 FOO=bar;将变量导出到我的环境中

如果我跑

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

有许多变体需要考虑:

  1. 只需创建一个名为value 的FOO=bar变量,但该变量不会传递到新进程:FOObar

    $ 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
    
  2. 运行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
    $
    
  3. FOO=foo; <command>相当于(1);在两个命令之间添加分号相当于在两个单独的行上运行这两个命令:

    $ FOO=foo; echo $FOO
    foo
    $ bash
    $ echo $FOO
    
    $ exit
    exit
    $ echo $FOO
    foo
    $
    
  4. 使用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

这里$FOOfromFOO=$FOO将被扩展分配FOO=bar发生。

您可以通过一个更直接的示例来检查这一点:

FOO=first
FOO=second echo FOO=$FOO
=> FOO=first

FOO=third; echo FOO=$FOO
=> FOO=third

表单确实会在 的环境中FOO=bar cmd设置,但是像这样的命令不会自动导出它的FOO=barcmddocker自己的环境到容器中,但环境变量必须使用开关显式添加-e

同样,更简单的演示是:

FOO=before
FOO=after env - FOO=$FOO printenv FOO
=> before

相关内容