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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:41:17