使用docker exec执行两个命令

25

我正在尝试在docker exec中执行两个命令。具体来说,我必须在特定目录内运行命令。我尝试过这样做,但它并没有起作用:

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

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

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

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


1
你尝试过这个命令吗:docker exec [id] /bin/bash -c 'cd /var/www/project && composer install' - Nehal J Wani
谢谢,老兄。我没看到你的评论,但它起作用了! - BraveAdmin
5个回答

40
在你的第一个例子中,你向docker exec命令传递了 -c 标志。答案很简单: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"

但是,正如您在评论中指出的那样,这也行不通。这是因为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'

1
你好,我尝试了你的命令,但是它没有起作用,显示了以下错误:rpc 错误:code = 2 desc = oci 运行时错误:exec 失败:container_linux.go:247:启动容器进程导致“exec: "cd /var/www/project && composer install":stat cd /var/www/project && composer install:没有这样的文件或目录”显然,该目录确实存在,因此我可以手动访问。 - BraveAdmin
@Adrià 是的,我没有想到这里要用 cd 命令。我更新了答案,虽然现在它基本上与你自己发布的答案相同(但解释了为什么它有效)。 - Dan Lowe

4

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

您很可能是从设置入口点为/bin/shdocker run命令中找到了这个语法。然而,exec绕过了入口点,所以您需要包含完整的要运行的命令。正如其他人指出的那样,该命令包括像bash或以下示例中的sh这样的shell:

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

2
其他答案可以让你运行两个任意命令。但是,如果第一个命令只是 cd,那么你应该使用 -w 选项来设置工作目录。
docker exec -w {dir} {container} {commands}

因此,在您的示例中:

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

2
正如 Nehal J Wani 在他的评论中所说,正确的语法是以下内容:
docker exec [id] /bin/bash -c 'cd /var/www/project && composer install'

许多感谢!

0

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

我需要通过ssh对docker容器执行复合docker exec命令。 我成功地完成了以下2个步骤:

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

-运行它的ssh命令

  1. 环境变量定义:

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

  2. 在远程系统上运行的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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接