bash 将带有参数的命令作为字符串传递给 docker run
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39443913/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Passing a command with arguments as a string to docker run
提问by davidA
The issue I'm facing is how to pass a command with arguments to docker run
. The problem is that docker run
does not take command plus arguments as a single string. They need to be provided as individual first-class arguments to docker run
, such as:
我面临的问题是如何将带参数的命令传递给docker run
. 问题是docker run
不将命令加参数作为单个字符串。它们需要作为单独的一流参数提供给docker run
,例如:
#!/bin/bash
docker run --rm -it myImage bash -c "(cd build && make)"
However consider the command and argument as the value of a variable:
但是,将命令和参数视为变量的值:
#!/bin/bash -x
DOCKER_COMMAND='bash -c "(cd build && make)"'
docker run --rm -it myImage "$DOCKER_COMMAND"
Unfortunately this doesn't work because docker run
doesn't understand the substitution:
不幸的是,这不起作用,因为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.
A slight change, removing the quotation of DOCKER_COMMAND
:
略有变化,删除了引用DOCKER_COMMAND
:
#!/bin/bash -x
DOCKER_COMMAND='bash -c "(cd build && make)"'
docker run --rm -it myImage $DOCKER_COMMAND
Results in:
结果是:
+ 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
How can I expand a string from a variable so that it is passed as a distinct command and arguments to docker run
inside a script?
如何从变量扩展字符串,以便将其作为不同的命令和参数传递到docker run
脚本内部?
采纳答案by larsks
Start with the syntax of the docker run
command, which is:
从docker run
命令的语法开始,即:
docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG...]
This means if you run:
这意味着如果你运行:
DOCKER_COMMAND='bash -c "(cd build && make)"'
docker run --rm -it myImage "$DOCKER_COMMAND"
You are passing the entirety of the $DOCKER_COMMAND
variable as the COMMAND
. You are asking Docker to find a file matching the name bash -c "(cd build && make)"
, so it should be no surprise that it fails. It doesn't have anything to do with "docker run doesn't understand the substitution". This is all related to the way your shell parses command lines before executing them.
您将整个$DOCKER_COMMAND
变量作为COMMAND
. 您要求 Docker 查找与 name 匹配的文件bash -c "(cd build && make)"
,因此它失败也就不足为奇了。它与“docker run 不理解替换”没有任何关系。这都与您的 shell 在执行命令行之前解析命令行的方式有关。
When you remove the quotes around $DOCKER_COMMAND
, you end up calling it like this (I'm putting each argument on a separate line to make it obvious):
当您删除 周围的引号时$DOCKER_COMMAND
,您最终会像这样调用它(我将每个参数放在单独的一行中以使其显而易见):
docker
run
--rm
-it
myImage
bash
-c
"(cd
build
&&
make)"
And that's not going to work, because bash is going to try to run the script "(cd
, which should make obvious the reason for the unexpected EOF while looking for matching
"'error. Bash's
-c` option only takes a single argument, but because of the way shell expansion works it's getting 4.
这行不通,因为 bash 将尝试运行脚本"(cd
,这应该很明显unexpected EOF while looking for matching
“' error. Bash's
-c` 选项只接受一个参数的原因,但由于 shell 扩展的工作方式,它得到了 4。
You could do it this way:
你可以这样做:
DOCKER_COMMAND='cd build && make'
docker run --rm -it myImage bash -c "$DOCKER_COMMAND"
(I've removed the parentheses around your command because they don't do anything the way you're using them.)
(我已经删除了您命令周围的括号,因为它们不会像您使用它们那样做任何事情。)
This way, you're calling docker run
with a command of bash
, and you're giving bash's -c
option a single argument (the contents of the $DOCKER_COMMAND
variable).
这样,您docker run
使用 的命令进行调用bash
,并且为 bash 的-c
选项提供了一个参数($DOCKER_COMMAND
变量的内容)。