【问题标题】:Passing a command with arguments as a string to docker run将带有参数的命令作为字符串传递给 docker run
【发布时间】:2017-01-19 12:19:24
【问题描述】:

我面临的问题是如何将带有参数的命令传递给docker run。问题是docker run 不将命令加参数作为单个字符串。它们需要作为单独的一等参数提供给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 很重要。)对我来说,这听起来像:“如何使用环境变量将参数解析到我的脚本。”
  • @MichaWiedenmann 感谢您的评论。实际上更多的是关于 Docker 如何接受参数,以及如何从环境变量中提取这些参数。这通常不会出现,因为大多数命令可以从带引号的字符串构建,但 docker 需要单独的参数。我会添加一些背景。
  • @MichaWiedenmann 好的,我已经大大简化了。

标签: linux bash shell docker variable-expansion


【解决方案1】:

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 不理解替换”没有任何关系。这都与您的 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 变量的内容)。

【讨论】:

  • 特别感谢您的解释,因为它帮助我理解了这两种形式之间的区别。我采纳了您将字符串传递给bash -c 的建议,非常适合我的应用。
猜你喜欢
  • 1970-01-01
  • 2017-04-13
  • 1970-01-01
  • 2020-08-19
  • 1970-01-01
  • 2018-12-29
  • 2017-01-12
  • 1970-01-01
  • 2019-11-20
相关资源
最近更新 更多