Bash $?变量赋值

Bash $? Variable Assignement

我刚开始学习 bash,我正在阅读 the $? variable。据我了解,$? 被分配给最后执行的命令的退出状态。

例如

$ false; echo $?

将产生 1,并且

$ false; :; echo $?

将产生 0

当我将这些与 if/for 块结合使用时,事情会变得有点复杂。手册页内容如下:

for NAME [in WORDS ... ] ; do COMMANDS; done

Execute commands for each member in a list.

The for loop executes a sequence of commands for each member in a list of items. If in WORDS ...; is not present, then in "$@" is assumed. For each element in WORDS, NAME is set to that element, and the COMMANDS are executed.

Exit Status:

Returns the status of the last command executed.

这意味着:

$ false; for i in 1 2 3; do false; done; echo $?

将产生 1,因为最后执行的命令是错误的。但是

$ false; for i in; do false; done; echo $?

$ false; if false; then :; fi; echo $?

尽管 false 是最后执行的命令,但仍会产生 0。

我的猜测是 $? 变量在进入 for/if 块时设置为 0。我错过了什么吗?

命令 $ false; for i in; do false; done; echo $? 给出 for loop 的退出状态。由于它没有错误地退出 for 循环,因此 $? 为 0。 这是一个类似的问题,可能会有所帮助。 How to get the exit status a loop in bash

是的,在 if ..;for ..;while ..; 语句后退出状态重置为 0。

需要说明的是,这并不意味着在 fi;done; 之后,因为退出状态是最后一个命令的退出状态。

编辑:if/elifthen 之间的命令不影响复合语句的退出状态,而在 then/[=20= 之间执行的最新命令]和elif/fi设置复合语句的退出状态。

函数调用后;退出状态将是 return 返回的值或上一个命令的退出状态。

选项 set -eset -o errexit; shell 在具有 <>0 退出状态的命令之后退出,除非后跟 || 或在 if ..; 语句内。

必须在命令退出后立即检查退出状态,可以使用逻辑运算符&&||:

# to fail fast the process can't continue
simple_command || {
    echo "failed .."
    exit 1
}

错误处理类似于异常,要问的问题是在命令失败后进程如何继续?

在管道命令中,退出状态是最后一个命令的退出状态,set -o pipefail 除外:退出状态将是管道中退出状态 <>0 的最新命令的退出状态。

根据bash's manual

if list ; then list ; [ elif list ; then list ; ] ... [ else list ; ] fi

The iflist is executed. If its exit status is zero, the thenlist is executed. Otherwise, each eliflist is executed in turn, and if its exit status is zero, the corresponding thenlist is executed and the command completes. Otherwise, the elselist is executed, if present. The exit status (of the whole if ... fi block) is the exit status of the last command (in the then, elif or else block) executed, or zero if no condition tested true.