AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 685697
Accepted
Vladan
Vladan
Asked: 2015-04-27 10:08:50 +0800 CST2015-04-27 10:08:50 +0800 CST 2015-04-27 10:08:50 +0800 CST

Docker CMD 指令中的多个命令

  • 772

当我尝试在运行时通过 Dockerfile 中的 CMD 指令执行两个命令时,不明白发生了什么。我认为这应该可行:

CMD ["/etc/init.d/nullmailer", "start", ";", "/usr/sbin/php5-fpm"]

但它不起作用。容器尚未启动。所以我不得不这样做:

CMD ["sh", "-c", "/etc/init.d/nullmailer start ; /usr/sbin/php5-fpm"]

我不明白。这是为什么?为什么第一行不是正确的方法?有人可以向我解释这些“CMD shell 格式与 JSON 格式等”的内容吗?简单来说。

请注意 -正如预期的那样,command:指令 in也是如此。docker-compose.yml

docker
  • 7 7 个回答
  • 294539 Views

7 个回答

  • Voted
  1. Best Answer
    Daniel t.
    2015-04-27T20:25:14+08:002015-04-27T20:25:14+08:00

    我相信差异可能是因为第二个命令执行 shell 处理,而第一个命令没有。根据官方文档,有exec和shell表格。您的第一个命令是一个exec表单。exec表单不会扩展环境变量,而表单shell会。exec由于它依赖于 shell 处理,通过使用该命令可能会失败。您可以通过运行检查这一点docker logs CONTAINERID

    你的第二个命令,shell 形式,相当于 -

    CMD /etc/init.d/nullmailer start ; /usr/sbin/php5-fpm

    文档摘录 -

    注意:与 shell 形式不同,exec 形式不调用命令 shell。这意味着不会发生正常的外壳处理。例如,CMD [ "echo", "$HOME" ]不会对$HOME. 如果你想要 shell 处理,那么要么使用 shell 形式,要么直接执行 shell,例如:CMD [ "sh", "-c", "echo", "$HOME" ].

    • 65
  2. Digital Human
    2019-08-07T00:55:42+08:002019-08-07T00:55:42+08:00

    不要让自己难受。只需创建一个 bash 文件“start.sh”: 

    #!/bin/bash
    
    /usr/bin/command2 param1
    /usr/bin/command1
    

    在你的 Dockerfile 中做:

    ADD start.sh /
    RUN chmod +x /start.sh
    
    CMD ["/start.sh"]
    
    • 62
  3. BMitch
    2019-08-08T06:47:27+08:002019-08-08T06:47:27+08:00

    CMD(and RUNand )的 json 语法ENTRYPOINT将参数作为 exec 系统调用直接传递给内核。在 exec 系统调用中,没有通过空格、转义引号、IO 重定向、变量替换、命令之间的管道、运行多个命令等将命令与参数分开。系统调用只需要运行可执行文件和传递给该可执行文件的参数列表,然后运行它。

    字符喜欢$扩展变量、;分隔命令、(空格)分隔参数、&&链接||命令、>输出重定向、|命令之间的管道等,这些都是 shell 的特性,需要类似/bin/shor的东西/bin/bash来解释和实现它们。


    如果您切换到 的字符串语法CMD,docker 将使用 shell 运行您的命令:

    CMD /etc/init.d/nullmailer start ; /usr/sbin/php5-fpm
    

    否则,您的第二种语法会执行完全相同的操作:

    CMD ["sh", "-c", "/etc/init.d/nullmailer start ; /usr/sbin/php5-fpm"]
    

    请注意,我不建议在容器内以这种方式运行多个命令,因为如果您的第一个命令失败,则不会进行错误处理,尤其是在它在后台运行时。您还在容器内留下一个以 pid 1 运行的 shell,这将中断信号处理,导致 10 秒延迟和 docker 不正常地杀死您的容器。可以使用 shellexec命令减轻信号处理:

    CMD /etc/init.d/nullmailer start ; exec /usr/sbin/php5-fpm
    

    但是,在后台静默处理进程失败需要您切换到某种多进程管理器,例如 supervisord,或者最好将您的应用程序分解为多个容器并使用 docker-compose 之类的东西部署它们。

    • 10
  4. devrimbaris
    2015-12-02T07:06:45+08:002015-12-02T07:06:45+08:00

    我猜第一个命令失败是因为在 DOCKER CMD 形式中,只有第一个参数被执行,其余的被输入到这个命令中。

    第二种形式有效,因为所有命令都用“;”分隔 被输入到执行它们的 sh 命令中。

    • 1
  5. Eyong Kevin Enowanyo
    2021-02-11T20:15:40+08:002021-02-11T20:15:40+08:00

    例如,假设您有两个要运行的 python 命令python init_reset.py和python app.py. 然后使用CMD,你可以将两个命令与单个命令结合起来

    CMD python init_reset.py ; python app.py
    
    • 1
  6. Mohammed Noureldin
    2021-10-20T12:03:11+08:002021-10-20T12:03:11+08:00

    在 Docker compose 中,这可以通过以下示例完成:

    command: ["sh", "-c", "
        apt update && apt install -y libldap-common;
        cp /ca.crt /usr/local/share/ca-certificates/;
        update-ca-certificates;
        exec apache2-foreground
      "]
    

    会将主可执行文件的exec上下文切换到 apache2-forground。

    • 1
  7. vedat
    2015-12-08T09:42:20+08:002015-12-08T09:42:20+08:00

    我认为您不应该在“开始”之后加上半逗号

    而不是使用

    CMD ["/etc/init.d/nullmailer", "start", ";", "/usr/sbin/php5-fpm"]
    

    尝试

    CMD ["/etc/init.d/nullmailer", "start", "/usr/sbin/php5-fpm"]
    

    由于 docker 使用“sh -c”,上面的命令将如下执行

    /etc/init.d/nullmailer start
    /etc/init.d/nullmailer /usr/sbin/php5-fpm
    
    • 0

相关问题

  • 如何调试 docker 容器初始化?

  • 创建后立即启动 Docker 容器?

  • 如何在不指定命令的情况下在 Docker 容器中运行完整的操作系统?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve