将带有参数的命令作为字符串传递给 docker 运行

Passing a command with arguments as a string to docker run

我面临的问题是如何将带有参数的命令传递给 docker run。问题是 docker run 不将命令加参数作为单个字符串。它们需要作为单独的 first-class 参数提供给 docker run,例如:

#!/bin/bash
docker run --rm -it myImage bash -c "(cd build && make)"

但是将命令和参数视为变量的值:

#!/bin/bash -x
DOCKER_COMMAND='bash -c "(cd build && make)"'
docker run --rm -it myImage "$DOCKER_COMMAND"

不幸的是,这不起作用,因为 docker run 不理解替换:

+ docker run --rm -it myImage 'bash -c "(cd build && make)"'
docker: Error response from daemon: oci runtime error: exec: "bash -c \"(cd build && make)\"": stat bash -c "(cd build && make)": no such file or directory.

略有改动,删除了 DOCKER_COMMAND:

的引用
#!/bin/bash -x
DOCKER_COMMAND='bash -c "(cd build && make)"'
docker run --rm -it myImage $DOCKER_COMMAND

结果:

+ docker run --rm -it myImage 'bash -c "(cd build && make)"'
build: -c: line 0: unexpected EOF while looking for matching `"'
build: -c: line 1: syntax error: unexpected end of file

如何从变量扩展字符串,以便它作为不同的命令和参数传递给脚本中的 docker run

docker run 命令的语法开始,即:

docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG...]

这意味着如果你 运行:

DOCKER_COMMAND='bash -c "(cd build && make)"'
docker run --rm -it myImage "$DOCKER_COMMAND"

您将整个 $DOCKER_COMMAND 变量作为 COMMAND 传递。您要求 Docker 查找与名称 bash -c "(cd build && make)" 匹配的文件,因此它失败也就不足为奇了。它与 "docker run doesn't understand the substitution" 没有任何关系。这都与您的 shell 在执行命令行之前解析命令行的方式有关。

当您删除 $DOCKER_COMMAND 周围的引号时,您最终会这样调用它(我将每个参数放在单独的一行以使其明显):

docker
run
--rm
-it
myImage
bash
-c
"(cd
build
&&
make)"

那是行不通的,因为 bash 将尝试 运行 脚本 "(cd,这应该使 unexpected EOF while looking for matching 的原因显而易见” 'error. Bash's-c` 选项只接受一个参数,但由于 shell 扩展的工作方式,它得到 4.

你可以这样做:

DOCKER_COMMAND='cd build && make'
docker run --rm -it myImage bash -c "$DOCKER_COMMAND"

(我已经删除了您命令周围的括号,因为它们不会按照您使用它们的方式执行任何操作。)

这样,您将使用 bash 命令调用 docker run,并为 bash 的 -c 选项提供一个参数( $DOCKER_COMMAND 变量的内容)。