docker run;& lt;多个COMMANDS>

我试图运行这样的多个命令。

docker run image cd /path/to/somewhere && python a.py

但是这给了我“没有这样的文件或目录”错误,因为它被解释为…

"docker run image cd /path/to/somewhere" && "python a.py"

似乎需要一些像“”或()这样的转义字符。

所以我也尝试了

docker run image "cd /path/to/somewhere && python a.py"
docker run image (cd /path/to/somewhere && python a.py)

但这些都没用。

我已经搜索了Docker运行参考,但没有找到任何关于转义字符的提示。

188873 次浏览

要在docker中运行多个命令,使用/bin/bash -c和分号;

docker run image_name /bin/bash -c "cd /path/to/somewhere; python a.py"

如果我们需要,当且仅当command1 (cd)返回零(无错误)退出状态时,将执行command2 (python),使用&&而不是;

docker run image_name /bin/bash -c "cd /path/to/somewhere && python a.py"

你可以通过以下几种方式做到这一点:

  1. 使用-w选项更改工作目录:

    -w,——workdir=""容器内的工作目录

    https://docs.docker.com/engine/reference/commandline/run/#set-working-directory--w < / p >

  2. 将整个参数传递给/bin/bash:

    docker run image /bin/bash -c "cd /path/to/somewhere; python a.py"
    

你也可以在Docker容器中使用管道命令,例如bash -c "<command1> | <command2>":

docker run img /bin/bash -c "ls -1 | wc -l"

但是,如果不调用远程shell,输出将被重定向到本地终端。

如果您想将结果存储在容器之外的一个文件中,也就是在您的本地机器上,您可以这样做。

RES_FILE=$(readlink -f /tmp/result.txt)


docker run --rm -v ${RES_FILE}:/result.txt img bash -c "cat /etc/passwd | grep root > /result.txt"

命令的结果将在本地机器的/tmp/result.txt中可用。

对于那些来这里想用docker-compose做同样事情的人来说,你只需要在bash -c前面加上引号,并用&&将多个命令连接在一起。

所以在OPs的例子中docker-compose run image bash -c "cd /path/to/somewhere && python a.py"

只是从@Eddy Hernandez的评论中做出一个适当的回答,这是非常正确的,因为Alpine是灰而不是灰。

问题现在指的是在Docker Alpine容器中启动一个shell,这意味着使用shash/bin/sh/bin/ash/

根据OP的问题:

docker run image sh -c "cd /path/to/somewhere && python a.py"

如果你运行的命令相对简单,bash -c工作得很好。但是,如果您试图运行一长串充满控制字符的命令,它可能会变得复杂。

我成功地绕过了这个问题,从外部将我的命令输入到进程中。

cat script.sh | docker run -i <image> /bin/bash

如果不明显,如果a.py总是需要在特定目录中运行,则创建一个简单的包装器脚本,该脚本执行cd,然后运行脚本。

在你的Dockerfile中,替换

CMD [ 'python', 'a.py' ]

或者其他

CMD [ '/wrapper' ]

并在你的根目录(或任何你方便的地方)创建一个脚本wrapper,内容如下

#!/bin/sh
set -e
cd /path/to/somewhere
python a.py

在许多情况下,也可以考虑重写a.py,这样它就不需要包装器了。要么在需要的地方设置为os.chdir(),要么让它在您在其环境或类似环境中配置的目录中查找其数据文件。

如果你不介意在子shell中运行命令,只需在要运行的多个命令周围加上一组外括号:

docker run image (cd /path/to/somewhere && python a.py)