GitHub Actions中Docker命令失败时如何捕获错误码并输出?
问题分析
- 交互式Shell导致退出状态丢失:使用
bash -ic启动交互式Shell时,交互式Shell不会将内部执行的pytest命令退出码传递给docker run。无论pytest是否失败,bash -i最终都会返回0,导致docker run的退出码始终为0。 - 状态判断逻辑错误:第二个
echo "Exit status: $?"获取的是前一条echo命令的退出码(永远是0),而非docker run命令的状态,后续的if判断完全失效。 - 管道行为影响状态捕获:即使开启
pipefail,由于docker run本身返回0,tee的成功状态会让整个管道的退出码保持为0。
修复方案
以下是满足所有需求的工作流配置:
name: Test Docker Command jobs: test: runs-on: ubuntu-latest steps: - name: Run test run: | # 禁用交互式Shell,直接执行命令 docker run tensorpod/pymimic3:latest \ bash -c "pytest tests/test_metrics" 2>&1 | tee output.txt # 捕获docker run的退出状态(管道第一个命令的状态) DOCKER_EXIT_CODE=${PIPESTATUS[0]} echo "Docker command exit code: $DOCKER_EXIT_CODE" # 根据docker run的状态判断是否终止步骤 if [ $DOCKER_EXIT_CODE -ne 0 ]; then echo "The Docker command failed because pytest exited with non-zero code." exit 1 fi
关键修复点
- 移除
bash -i选项:使用非交互式的bash -c执行命令,这样容器内的bash会将pytest的退出码传递给docker run,保证docker run的退出码与pytest一致。 - 正确捕获管道状态:用变量保存
${PIPESTATUS[0]}(管道中第一个命令docker run的退出码),避免后续命令覆盖$?的值。 - 基于正确状态判断终止:直接使用
docker run的退出码进行判断,确保pytest失败时步骤能正确终止。
需求满足情况
- 实时查看输出:
tee命令会将输出同时打印到GitHub Actions日志和文件,实现实时查看。 - 保存输出到文件:输出被写入
output.txt文件,可后续步骤使用或下载。 - 捕获错误状态:通过
${PIPESTATUS[0]}准确获取docker run的退出码,反映容器内pytest的执行结果。 - 失败时终止步骤:当
docker run退出码非0时,执行exit 1终止当前步骤,标记工作流为失败。
内容的提问来源于stack exchange,提问作者Amadou cisse
相关产品推荐
相关产品推荐

