313

我正在尝试运行这样的多个命令。

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

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

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

似乎需要一些 ESCAPE 字符,如 "" 或 ()。

所以我也试过

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

但这些没有用。

我搜索了Docker Run Reference,但没有找到任何关于 ESCAPE 字符的提示。

4

9 回答 9

531

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

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

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

docker run image_name /bin/bash -c "cd /path/to/somewhere && python a.py"
于 2015-02-13T01:07:53.180 回答
34

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

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

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

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

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

    docker run image /bin/bash -c "cd /path/to/somewhere; python a.py"
    
于 2015-02-13T17:44:46.660 回答
12

您还可以在 Docker 容器中通过管道传输命令,bash -c "<command1> | <command2>"例如:

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

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

于 2017-01-05T16:31:27.157 回答
10

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

我通过将我的命令从外部传递到进程中成功地解决了这个问题,即

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

于 2020-04-20T10:56:57.980 回答
5

只是为了从@Eddy Hernandez 的评论中做出正确的回答,这是非常正确的,因为 Alpine 带有 ash 而不是 bash。

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

基于OP的问题:

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

于 2020-02-11T15:17:52.657 回答
3

如果要将结果存储在容器外部的一个文件中,在本地计算机中,您可以执行类似的操作。

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在您的本地计算机中可用。

于 2018-10-02T15:51:14.823 回答
2

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

docker run image (cd /path/to/somewhere && python a.py)
于 2021-10-12T08:53:50.657 回答
2

对于其他来这里希望与docker-compose您做同样事情的人,只需要在bash -c多个命令前面加上引号,并用&&.

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

于 2019-01-04T07:10:41.460 回答
0

如果不是很明显,如果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()在需要的地方,要么让它在你在其环境或类似环境中配置的目录中查找它的数据文件。

于 2021-06-21T10:57:46.260 回答