使用 docker exec 执行两个命令

Posted

技术标签:

【中文标题】使用 docker exec 执行两个命令【英文标题】:Execute two commands with docker exec 【发布时间】:2017-06-19 22:26:25 【问题描述】:

我正在尝试在 docker exec 中执行两个命令。具体来说,我必须在特定目录中运行命令。 我试过了,但是没有用:

docker exec [id] -c 'cd /var/www/project && composer install'

未检测到参数-c。 我也试过这个:

docker exec [id] cd /var/www/project && composer install

但是composer install 命令是在docker exec 命令之后执行的。 我该怎么做?

【问题讨论】:

你试过了吗:docker exec [id] /bin/bash -c 'cd /var/www/project && composer install' 谢谢老兄,我没有看到你的评论,但它有效! 【参考方案1】:

在您的第一个示例中,您将-c 标志提供给docker exec。这是一个简单的答案:docker exec 没有 -c 标志。

在您的第二个示例中,您的 shell 甚至在 Docker 看到它之前将其解析为两个命令。相当于这样:

if docker exec [id] cd /var/www/project
then
    composer install
fi

首先,docker exec 运行,如果它退出 0(成功),composer install 将尝试在 Docker 外部本地运行

您需要做的是使用字符串将两个命令作为单个参数传递给docker exec。然后它们将不会被 shell 解释,直到它们已经在容器中。

docker exec [id] "cd /var/www/project && composer install"

但是,正如您在 cmets 中所指出的,这也不起作用。那是因为cd 是一个内置的shell,它本身并不存在。尝试将其作为初始命令执行将失败。所以下一步就是把它交给一个shell来执行。

docker exec [id] "bash -c 'cd /var/www/project && composer install'"

最后,此时 && 已移入一组内部引号,因此我们真的不需要 bash 命令周围的引号...如果您愿意,可以删除它们。

docker exec [id] bash -c 'cd /var/www/project && composer install'

【讨论】:

嗨,我试过你的命令,但它不起作用,这是显示的错误:rpc 错误:代码 = 2 desc = oci 运行时错误:执行失败:container_linux.go:247:启动容器进程导致“ exec: \"cd /var/www/project && composer install\": stat cd /var/www/project && composer install: no such file or directory" 显然,该目录确实存在,所以我可以手动访问。 @Adrià 是的,我没想到cd 是这里的命令。我更新了答案,尽管它现在或多或少与您自己发布的答案相匹配(但对它的工作原理有更多解释)。【参考方案2】:

容器 id 之后的所有内容都是要运行的命令,因此在第一个示例中,-c 不是 exec 的选项,但是 docker 尝试运行命令但由于该命令不存在而失败。

您很可能从 docker run 命令中找到此语法,其中入口点设置为 /bin/sh。但是, exec 会绕过入口点,因此您需要包含完整的命令才能运行。正如其他人指出的那样,该命令包括一个 shell,如 bash 或在下面的示例中,sh:

docker exec [id] /bin/sh -c 'cd /var/www/project && composer install'

【讨论】:

【参考方案3】:

如果您想运行 2 个任意命令,其他答案都可以。但是如果第一个命令只是cd,那么你应该使用-w选项来设置工作目录。

docker exec -w dir container commands

所以在你的例子中:

docker exec -w /var/www/project container composer install

【讨论】:

【参考方案4】:

正如 Nehal J Wani 在他的评论中所说,正确的语法如下:

docker exec [id] /bin/bash -c 'cd /var/www/project && composer install'

非常感谢!

【讨论】:

【参考方案5】:

我想在这里添加我的示例,因为它比上面显示的要复杂一些。此示例还说明了如何查找应在 docker exec 命令中使用的容器 ID。

我需要通过 ssh 对 docker 容器执行复合 docker exec 命令。 我设法通过两个步骤实现了这一目标:

-定义包含作为环境变量导出的命令的变量

-ssh 命令运行它

    环境变量定义:

    export COMMAND="bash -c 'php bin/console --version && composer --version'"

    在远程系统上运行的 ssh 命令:

ssh -t -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i keyfile.pem ec2-user@111.222.111.222 'docker exec docker ps|grep php|grep api|grep -v cron|awk '"'"'print $1'"'"''$COMMAND

如您所见,我将命令放在单引号之外,以便将其实际值传递给 SSH 进程

命令执行的输出为:

Warning: Permanently added '111.222.111.222' (ECDSA) to the list of known hosts.
Cannot load Xdebug - it was already loaded
Symfony 4.3.5 (env: dev, debug: true)
Cannot load Xdebug - it was already loaded
Composer version 1.9.1 2019-11-01 17:20:17
Connection to 111.222.111.222 closed.

如果您希望在一行中执行此命令,您可以使用我的第一个示例的一些修改版本:

COMMAND="bash -c 'php bin/console --version && composer --version'" ssh -t -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i keyfile.pem ec2-user@111.222.111.222 'docker exec `docker ps|grep php|grep api|grep -v cron|awk '"'"'print $1'"'"'` '$COMMAND

【讨论】:

以上是关于使用 docker exec 执行两个命令的主要内容,如果未能解决你的问题,请参考以下文章

docker下容器怎么执行命令

如何在每个“exec”命令中执行 Docker 映像的入口点?

19-Docker-常用命令详解-docker exec

exec...的docker中的EXEC

docker 命令详解:exec

Docker 命令- exec命令