我需要在我的 shell 脚本中知道一些 docker exec 命令的输出,例如我有一个 nginx 容器,并且在我的脚本中运行:
docker exec -it containerName /etc/init.d/nginx configtest
我只想在 nginx 配置测试成功时继续执行脚本,而不是在失败时继续执行。
我尝试过使用
$?
,但它是0
,即使configtest输出失败(因为据我所知,docker exec已成功执行)。
我发现this工作得很好:
docker exec -t -i my-container sh -c 'my-command; exit $?'
将我的评论转化为答案。这应该有效:
docker exec -it mynginx /etc/init.d/nginx configtest && echo "pass" || echo "fail"
它对我有用。
api/client/exec.go#L97-L100
确实获得了退出代码:
var status int
if _, status, err = getExecExitCode(cli, execID); err != nil {
return err
}
api/client/utils.go#L84-L97
// getExecExitCode perform an inspect on the exec command. It returns
// the running state and the exit code.
func getExecExitCode(cli *DockerCli, execID string) (bool, int, error) {
resp, err := cli.client.ContainerExecInspect(execID)
if err != nil {
// If we can't connect, then the daemon probably died.
if err != lib.ErrConnectionFailed {
return false, -1, err
}
return false, -1, nil
}
return resp.Running, resp.ExitCode, nil
}
因此,如果您的命令失败,您将获得退出代码。
虽然,如这里提到的,您可以使用
nginx -t
而不是 configtest
。
如果您不想立即响应由
docker exec
命令触发的进程返回的退出代码,您可以执行以下操作。
docker exec my-app-container /app/scripts/test.sh
UNIT_TEST_EXIT_CODE=$? # Get exit code from last command (/app/scripts/test.sh)
... # do some stuff after unit testing
exit $UNIT_TEST_EXIT_CODE
我在 CI/CD 管道的背景下使用了这种方法。
准备测试运行 bash 命令的新版本:
docker exec -t -i oracle bash -c "echo hola && exit"
hola
截至 2024 年(docker 版本 27.0.3),
docker exec
返回进程的退出代码:
$ docker exec 0f728ea39295 sh -c 'exit 100' ; echo $?
100
代码是这里,它似乎从2016年,版本17.06开始存在