【问题标题】:docker run <IMAGE> <MULTIPLE COMMANDS>docker run <图像> <多个命令>
【发布时间】:2015-04-13 23:31:05
【问题描述】:

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

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

【问题讨论】:

  • 请注意,对于这种特殊用途,docker run 有一个 -w/--workdir 参数。 docker run -w /path/to/somewhere image python a.py

标签: docker docker-image


【解决方案1】:

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

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

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

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

【讨论】:

  • 感谢您的提示!我只是尝试了 [ docker run image "cd /bin; ls" ] 并收到以下错误消息。 [ 执行:“cd /bin;ls”:stat cd /bin; ls:没有这样的文件或目录] [来自守护进程的错误响应:无法启动容器]
  • 任何发现此答案的人都可能对如何使用此处的文档向容器提供命令感兴趣:here's my answer to another question like this about here documents, feel free to check it out
  • docker run alpine sh -c "ls | wc &gt;&gt; xxx" 这对我有很大帮助,当 bash 不可用时。
  • 这适用于cd,但不适用于返回码很重要;&amp;&amp; 不同的情况,请参阅unix.stackexchange.com/questions/37069/…
  • 感谢@NickZalutskiy,您的评论更新了答案
【解决方案2】:

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

  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"
    

【讨论】:

    【解决方案3】:

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

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

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

    【讨论】:

      【解决方案4】:

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

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

      cat script.sh | docker run -i &lt;image&gt; /bin/bash

      【讨论】:

        【解决方案5】:

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

        问题现在涉及Starting a shell in the Docker Alpine container,这意味着使用shash/bin/sh/bin/ash/

        基于 OP 的问题:

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

        【讨论】:

          【解决方案6】:

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

          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 的形式提供。

          【讨论】:

            【解决方案7】:

            对于来到这里希望对docker-compose 执行相同操作的其他人,您只需在bash -c 前面加上引号,将多个命令与&amp;&amp; 连接在一起。

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

            【讨论】:

            • 这个对我有用,但是命令执行后docker进程退出
            • 我该如何退出这样的 docker 进程?按 ctrl C 或 ctrl Z 或键入 exit 不起作用还是我必须通过 docker stop 命令将其杀死?
            • docker-compose down [service-name] 不起作用还是? (不用担心,欢迎您,乐于提供帮助:))
            【解决方案8】:

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

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

            【讨论】:

              【解决方案9】:

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

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2021-10-09
                • 2018-02-23
                • 2015-11-14
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多