为何exit状态在命令行有效但在Bash脚本中无效?
解决Docker容器内命令退出状态捕获及Git pre-commit脚本问题
我来帮你理清这个问题,核心是要正确捕获容器内命令的退出码,同时处理stderr输出,并且把逻辑顺畅地写到Git pre-commit脚本里。
首先纠正一个小误区:你不需要在容器内的命令里追加echo $exitStatus,因为docker-container ssh(或者更常用的docker exec)本身会把容器内最后一条命令的退出码作为自身的退出码返回给主机系统。也就是说,容器里执行exit 25,主机上运行这个Docker命令后的$?就是25,直接用这个就够了。
正确的命令写法
要同时实现「将容器内命令的stderr输出到主机的/tmp/stderr」和「捕获退出状态」,可以这么写:
# 执行容器内命令,重定向stderr到主机的/tmp/stderr docker-container ssh -c"echo 'YAY!'; exit 25;" 2>/tmp/stderr # 把退出状态保存到变量 exit_status=$?
整合到Git pre-commit脚本的完整示例
下面是一个可以直接用的pre-commit脚本模板,逻辑清晰,符合Git钩子的要求:
#!/bin/bash # 替换成你的容器名称或ID TARGET_CONTAINER="your-container-id-or-name" # 执行容器内的目标命令,重定向stderr到临时文件 docker-container ssh -c"# 这里替换成你实际要执行的命令 echo 'Running pre-commit checks in container...' # 比如你的业务命令:lint、test等 exit 25 # 模拟失败场景,实际换成你的命令" 2>/tmp/pre-commit-stderr # 捕获容器命令的退出码 exit_status=$? # 根据退出状态处理逻辑 if [ $exit_status -ne 0 ]; then echo "❌ 容器内预检查失败,退出码:$exit_status" echo "详细错误信息请查看:/tmp/pre-commit-stderr" # 返回非0值,阻止Git提交 exit 1 fi # 检查通过,允许提交 echo "✅ 容器内预检查通过" exit 0
关键要点说明
- 退出码传递:Docker的执行命令(不管是
docker exec还是你用的docker-container ssh)都会直接把容器内命令的退出码返回给主机,所以$?就是你要的exitStatus,无需额外在容器内输出。 - stderr重定向:
2>/tmp/stderr必须放在Docker命令的末尾,这样才能把容器内命令的标准错误输出重定向到主机的指定文件中。 - Git钩子逻辑:Git pre-commit脚本只要最后返回非0值,就会阻止提交,所以我们根据
exit_status的值决定脚本的最终退出码即可。
内容的提问来源于stack exchange,提问作者TylerMills
相关产品推荐
相关产品推荐

