将 ENV 传递给 Docker 容器 运行 单个命令

Pass ENV to Docker container running single command

这会打印出空白:

docker run --rm --env HELLO="world" ubuntu:18.04 bash -c "echo $HELLO"

然而这有效:

docker run --rm -it --env HELLO="world" ubuntu:18.04 bash
# in the container
echo $HELLO

HELLO 似乎传递给了容器:

docker run --rm --env HELLO="world" ubuntu:18.04 env

为什么第一个命令没有看到 HELLO?我错过了什么?

由于双引号,一旦命令在进入容器之前执行,$HELLO 将由 docker 主机本身评估。因此,您需要使用反斜杠 (\) 转义美元符号 ($),它告诉 bash $ 是命令本身的一部分,不需要由当前 shell(在我们的例子中是 docker 主机)进行评估或使用单引号 (''),如下所示:

使用单引号

$ docker run --rm --env HELLO="world" ubuntu:18.04 bash -c 'echo $HELLO'
world

使用反斜杠转义

$ docker run --rm --env HELLO="world" ubuntu:18.04 bash -c "echo $HELLO"
world

您没有看到预期内容的原因是,在您期望对事物进行评估之前对其进行了评估。

当你运行:

docker run --rm --env HELLO="world" ubuntu:18.04 bash -c "echo $HELLO"

"echo $HELLO" 和 bash 真的没有什么不同:

echo "echo $HELLO"

shell (bash) 解析双引号 (") 和其中的内容。它看到 "echo $HELLO" 并用它的值替换变量 $HOME。如果未定义 $HOME,则计算结果为 echo.

所以,

echo "echo $HELLO"

由您的 shell 解析和评估。最后就是 运行s 这个:

echo "echo "

因此 docker 命令中的 "echo $HELLO" 被评估为 "echo " 并且 那是 传递给 docker 的内容命令。

你想要做的是阻止你的 shell 评估变量。您可以通过几种方式完成:

  1. 您可以使用单引号代替双引号。您的 shell 没有解析它;它将按原样传递到容器内的 bash

    docker run --rm --env HELLO="world" ubuntu:18.04 bash -c 'echo $HELLO'
    
  2. 您可以转义 $ 以避免在此 shell 中对其求值,并让 docker 容器内的 bash 对其求值:

    docker run --rm --env HELLO="world" ubuntu:18.04 bash -c "echo $HELLO"