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

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运行参考,但没有找到任何关于转义字符的提示。


当前回答

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

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

其他回答

TL; diana;

$ docker run --entrypoint /bin/sh image_name -c "command1 && command2 && command3"

关于已接受答案的一个问题如下。

没有人提到docker run image_name /bin/bash -c只是将一个命令附加到入口点。一些流行的图像足够智能,可以正确处理这些信息,但有些则不行。

想象一下下面的Dockerfile:

FROM alpine
ENTRYPOINT ["echo"]

如果你试着以echo的形式构建它并运行:

$ docker run echo /bin/sh -c date

您的命令将被追加到入口点,因此结果将是echo "/bin/sh -c date"。

相反,你需要重写入口点:

$ docker run --entrypoint /bin/sh echo -c date

Docker运行参考

要在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"

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

在Dockerfile中替换

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

或者其他

CMD [ '/wrapper' ]

并在根目录(或任何对您方便的地方)中创建一个包含以下内容的脚本包装器

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

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

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

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

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

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

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

根据OP的问题:

Docker运行image sh -c "cd /path/to/somewhere && python a.py"