Bash脚本中将$?赋值给变量后,为何变量始终显示0?
解决Bash脚本中退出码变量始终为0的问题
我明白你遇到的问题了——直接在if-else分支里打印$?能得到正确的0或1,但提前把$?赋值给变量后,这个变量就一直是0,完全没反应后续命令的结果。这其实是对Bash里$?的工作机制理解不到位导致的,我给你拆解下原因和解决办法:
问题根源
你在脚本最开头就执行了exit=echo $?``,这时候脚本刚启动,还没运行任何可能产生非0退出码的命令,所以$?的值默认是0。这个值一旦赋给exit变量就固定了,后续不管你执行stat命令还是条件判断,exit变量都不会自动更新——因为$?只保存上一条执行命令的退出码,但它不会主动同步到你之前定义的变量里。
而你在分支里直接echo $?能得到正确结果,是因为此时$?保存的是刚刚执行的[[ $(stat ...) == "777" ]]这个条件判断的退出码(0表示判断为真,1表示为假),每次分支执行时$?都是最新的。
解决方案
根据你的需求,分两种情况处理:
情况1:想获取条件判断([[ ... ]])的退出码
不需要提前赋值变量,而是进入分支后立即把$?赋值给变量,这样拿到的就是当前判断的结果:
#!/bin/bash DIRECTORY="/some/dir" if [[ $(stat -c "%a" "$DIRECTORY") == "777" ]] then exit_code=$? echo $exit_code echo "The exit code is: $exit_code" else exit_code=$? echo $exit_code echo "The exit code is: $exit_code" fi
情况2:想获取stat命令本身的退出码(比如目录不存在时stat执行失败的情况)
这种情况不能把stat直接嵌套在[[ ]]里,因为此时$?会变成条件判断的结果,而不是stat的退出码。正确做法是先单独执行stat,保存它的输出和退出码,再进行判断:
#!/bin/bash DIRECTORY="/some/dir" # 先执行stat命令,保存输出和退出码 perm=$(stat -c "%a" "$DIRECTORY") exit_code=$? # 先检查stat是否执行成功 if [[ $exit_code -eq 0 ]]; then # 再判断权限是否为777 if [[ $perm == "777" ]]; then echo "Directory has 777 permissions" echo "stat exit code: $exit_code, permission check exit code: $?" else echo "Directory doesn't have 777 permissions" echo "stat exit code: $exit_code, permission check exit code: $?" fi else echo "Failed to get directory permissions" echo "stat exit code: $exit_code" fi
关键提醒
$?是一次性的动态值,每次执行任何命令(包括变量赋值、条件判断)都会覆盖它的值,所以必须在你关心的命令执行后立即获取它。- 不要提前赋值
$?到变量里,除非你确定那就是你要的最终退出码。
内容的提问来源于stack exchange,提问作者slaffcheff
相关产品推荐
相关产品推荐

