You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Groovy脚本中传递Docker命令的退出状态?

问题

我需要从生成的Shell脚本中运行Docker命令,并将该Docker命令的退出状态返回至Groovy阶段,多次尝试后仍未成功。以下是我的代码:

def statusCode
def script_shell_code
script_shell_code = """
#!/bin/bash -x
pwd
docker run --rm  \
    my_docker.aws.us-east-1.amazonaws.com/${dockerImage} \
    /bin/bash -c 'tar -czf; exit_code=\$?; echo code \$exit_code; exit \$exit_code'
    exit_code2=\$?; echo code \$exit_code2; exit \$exit_code2
"""
steps.echo script_shell_code
println("script_shell_code: ${script_shell_code}")

statusCode = steps.sh(returnStatus:true, script: script_shell_code)
steps.echo "script return status: ${statusCode}"

输出结果如下:

+ pwd
/home/ubuntu/.jenkins/workspace/myworkspace1
+ docker run --rm  my_docker.aws.us-east-1.amazonaws.com/linux_release:tagv14 /bin/bash -c tar -czf; exit_code=0; echo code ; exit 
tar: option requires an argument -- 'f'
Try 'tar --help' or 'tar --usage' for more information.
code
+ exit_code2=0
+ echo code 0
code 0
+ exit 0

script return status110: 0

失败的tar命令本应返回状态码64,但该状态码丢失,最终获取到的状态码为0。如何让statusCode获取到真实的错误值64?

解决方案

核心问题分析

你的Shell脚本存在两个关键问题:

  1. 命令拆分导致逻辑失效:docker run后的容器内命令被宿主机Shell错误拆分,实际变成了三个独立命令:docker run ... /bin/bash -c tar -czf、exit_code=0、echo code ; exit。这使得exit_code2捕获的是docker run本身的退出码(只要容器启动成功就返回0),而非容器内tar命令的失败码。
  2. 多余的中间变量干扰:额外定义的exit_code2覆盖了docker run返回的真实容器退出码,最终返回了错误的0。

修复后的代码

Groovy部分

def statusCode
def script_shell_code
script_shell_code = """
#!/bin/bash -x
pwd
# 执行docker命令并直接传递其退出码
docker run --rm  \
    my_docker.aws.us-east-1.amazonaws.com/${dockerImage} \
    /bin/bash -c 'tar -czf; exit_code=\$?; echo code \$exit_code; exit \$exit_code'
# 直接返回docker命令的退出码给Groovy
exit \$?
"""
steps.echo script_shell_code
println("script_shell_code: ${script_shell_code}")

statusCode = steps.sh(returnStatus:true, script: script_shell_code)
steps.echo "script return status: ${statusCode}"

关键修改说明

  • 移除冗余的exit_code2逻辑:直接用exit $?返回docker run的退出码,而docker run默认会将容器内主进程的退出码(也就是tar命令的64)作为自身的退出码返回。
  • 确保容器内命令完整性:容器内的/bin/bash -c参数用单引号包裹,保证内部命令逻辑在容器内完整执行,不会被宿主机Shell拆分。

额外优化(可选)

如果需要更明确地指定容器内进程的退出码传递,可以添加--exit-code-from参数(默认就是主进程,所以非必须):

docker run --rm --exit-code-from main \
    my_docker.aws.us-east-1.amazonaws.com/${dockerImage} \
    /bin/bash -c 'tar -czf; exit_code=$?; echo code $exit_code; exit $exit_code'
exit $?

内容的提问来源于stack exchange,提问作者Anton K

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 03:32:44