docker运行<IMAGE> <MULTICOMMAND>


254

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

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字符的任何提示。

Answers:


439

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

谢谢您的提示!我只是尝试[docker run image“ cd / bin; ls”]并收到以下错误消息。[exec:“ cd / bin; ls”:统计cd / bin; ls:没有这样的文件或目录] [来自守护程序的错误响应:无法启动容器]
ai0307 2015年

1
任何人都可以找到此答案的,可能是对如何使用here文档将命令馈送到容器感兴趣:这是我对另一个关于here文档的类似问题的答案,请随时查看
Kohányi罗伯特

14
docker run alpine sh -c "ls | wc >> xxx"当bash不可用时,这对我有很大帮助。
Eddy Hernandez

1
此作品cd,但不是东西的地方返回代码事情;是不一样的&&unix.stackexchange.com/questions/37069/...
尼克Zalutskiy

1
谢谢@NickZalutskiy,用您的评论更新了答案
anhlc '18年

31

您可以通过以下两种方法执行此操作:

  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"
    

--workdir在提供的链接中未提及。该页面可能已移动/更改。可以更新到docs.docker.com/engine/reference/run/#workdirdocs.docker.com/engine/reference/commandline/run
marcv

10

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

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

但是,在不调用远程shell的情况下,输出将被重定向到本地终端。


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


2

对于来这里寻求与之相同的任何人,docker-compose您只需在前面加上bash -c多个命令并将其括在引号中,并与一起加入&&

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


这对我
有用,

以及如何退出这样的docker进程?按Ctrl C或Ctrl Z或键入exit不起作用,还是必须通过docker stop命令将其杀死?
node_man

不起作用docker-compose down [service-name]还是?(无后顾之忧不客气,乐于帮助:))
秒。

2

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

现在的问题referes到开始在码头工人高山容器外壳,这意味着使用shash/bin/sh/bin/ash/

基于OP的问题:

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


1

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

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.