使用 docker exec 执行两个命令
Execute two commands with docker exec
我正在尝试在 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
命令之后执行的。
我该怎么做?
在您的第一个示例中,您将 -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"
但是,正如您在评论中指出的那样,这也不起作用。那是因为 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'
正如 Nehal J Wani 在他的评论中所说,正确的语法如下:
docker exec [id] /bin/bash -c 'cd /var/www/project && composer install'
非常感谢!
容器 ID 之后的所有内容都是 运行 的命令,因此在第一个示例中 -c
不是 exec 的选项,但命令 docker 尝试 运行 并失败,因为该命令不存在。
您很可能是从入口点设置为 /bin/sh
的 docker run
命令中找到此语法的。但是,exec 会绕过入口点,因此您需要将完整命令包含到 运行。正如其他人所指出的那样,该命令包括 shell 之类的 bash 或在下面的示例中, sh:
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
我想在这里添加我的示例,因为它比上面显示的要复杂一些。此示例还说明了如何查找应在 docker exec 命令中使用的容器 ID。
我需要通过 ssh 对 docker 容器执行复合 docker exec 命令。
我设法通过 2 个步骤实现了这一目标:
-包含作为环境变量导出的命令的变量的定义
-运行它的ssh命令
环境变量定义:
导出命令="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 }'"'"'
'$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 }'"'"'` '$COMMAND
我正在尝试在 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
命令之后执行的。
我该怎么做?
在您的第一个示例中,您将 -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"
但是,正如您在评论中指出的那样,这也不起作用。那是因为 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'
正如 Nehal J Wani 在他的评论中所说,正确的语法如下:
docker exec [id] /bin/bash -c 'cd /var/www/project && composer install'
非常感谢!
容器 ID 之后的所有内容都是 运行 的命令,因此在第一个示例中 -c
不是 exec 的选项,但命令 docker 尝试 运行 并失败,因为该命令不存在。
您很可能是从入口点设置为 /bin/sh
的 docker run
命令中找到此语法的。但是,exec 会绕过入口点,因此您需要将完整命令包含到 运行。正如其他人所指出的那样,该命令包括 shell 之类的 bash 或在下面的示例中, sh:
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
我想在这里添加我的示例,因为它比上面显示的要复杂一些。此示例还说明了如何查找应在 docker exec 命令中使用的容器 ID。
我需要通过 ssh 对 docker 容器执行复合 docker exec 命令。 我设法通过 2 个步骤实现了这一目标:
-包含作为环境变量导出的命令的变量的定义
-运行它的ssh命令
环境变量定义:
导出命令="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 }'"'"'
'$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 }'"'"'` '$COMMAND