移除echo语句后GitHub Action以退出码1失败的问题排查
问题分析:移除echo语句后GitHub Action步骤退出码1失败
问题场景
以下是GitHub Action中的步骤代码:
- if: ${{ steps.cache-images.outputs.cache-hit == 'true' }} name: Load saved docker images run: | if [[ -f docker-images-backup/apisix-images.tar ]]; then [[ ${{ steps.test_env.outputs.type }} != first ]] && sudo ./ci/init-${{ steps.test_env.outputs.type }}-test-service.sh before docker load --input docker-images-backup/apisix-images.tar make ci-env-up project_compose_ci=ci/pod/docker-compose.${{ steps.test_env.outputs.type }}.yml echo "loaded docker images" echo test_type: [[ ${{ steps.test_env.outputs.type }} != first ]] && sudo ./ci/init-${{ steps.test_env.outputs.type }}-test-service.sh after && echo "executed" fi echo "exited if"
移除最后一行调试用的echo "exited if"后,该步骤始终以退出码1失败,但本地用不同变量组合运行脚本均正常。疑惑shell脚本是否存在类似C语言增减打印语句引发段错误的风险,寻求原因分析。
原因解析
这和C语言的段错误完全无关,核心原因是shell脚本的退出码由最后执行的命令决定,GitHub Action会把run脚本的最终退出码作为步骤是否成功的判断依据(非0即失败):
- 保留
echo "exited if"时,这条命令几乎必然执行成功(退出码0),因此整个步骤的退出码被覆盖为0,即使if块内之前的命令有非0退出码,也不会导致步骤失败。 - 移除该
echo后,脚本的退出码由if语句块的最后一条执行命令的退出码决定:- 若
docker-images-backup/apisix-images.tar不存在,if块不执行,此时脚本无有效命令执行,默认退出码为0,不会失败(这种情况可排除)。 - 若
if块执行,问题大概率出在最后一条命令:[[ ${{ steps.test_env.outputs.type }} != first ]] && sudo ./ci/init-${{ steps.test_env.outputs.type }}-test-service.sh after && echo "executed"。当steps.test_env.outputs.type不等于first时,init-...-test-service.sh after脚本执行失败(返回非0退出码),这条组合命令的退出码就是该脚本的非0值,成为整个run脚本的最终退出码,导致GitHub Action步骤标记失败。
- 若
- 本地测试正常的可能原因:本地环境中
init-...-test-service.sh after执行成功,或者本地未关注脚本最终退出码,或者本地环境的变量值、依赖状态与GitHub Action Runner不同。
排查建议
- 在GitHub Action中开启调试日志(添加
ACTIONS_STEP_DEBUG: true到环境变量),可查看每一条命令的执行结果和退出码,定位具体失败的命令。 - 若需临时屏蔽错误(不推荐,建议修复根本问题),可在
if块末尾添加true命令,强制让脚本最后一条命令返回0,但这会掩盖真实错误。 - 给脚本添加
set -e(开头加入set -e),让脚本遇到非0退出码的命令时立即终止,方便快速定位错误位置。
内容的提问来源于stack exchange,提问作者Shreemaan Abhishek
相关产品推荐
相关产品推荐

