# 用 exit 显式指定退出状态 > bash > exit 98 exit > echo $? 98 # 什么也不执行则退出状态为 0 > bash exit # Ctrl + D 退出 > echo $? 0 # 默认为最后一条命令的退出状态 > bash > ecasd ecasd: command not found exit # Ctrl + D 退出 > echo $? 127
在 bash 中对不同种类命令的退出状态作出如下规定:
内置命令: 由于内置命令执行时不需要启动额外的子进程, 因此需要用返回值模拟退出状态. 每个函数都定义了自己的退出状态, 例如: 内置命令 source 将脚本文件的最后一个命令的返回状态作为命令的返回状态. bash 中所有的内置命令都用退出状态 2 表示用法错误, 例如: 选项错误, 缺少参数.
> cd -+- # 错误的参数 bash: cd: -+: invalid option cd: usage: cd [-L|[-P [-e]] [-@]] [dir] > echo $? 2
外部命令: 外部命令的退出状态就是使用 waitpid 得到的子进程的退出状态, 如果子进程在执行过程被编号为 N 的信号所终止, 则得到的退出状态就为 128+N .
Shell 函数: 定义 shell 函数时, 函数名与之前已定义的只读函数名相同则退出状态为 1 , 当发生语法错误则退出状态为 2 . 执行 shell 函数时, 函数中最后执行的一条命令的退出状态就是整个函数的退出状态.
# 二次定义只读函数报错
> func () { echo; }
> readonly -f func
> func; echo $?
0
> func () { echo poi; }
bash: func: readonly function
> echo $?
1
# 定义函数发生语法错误
> fune () {aa}
bash: syntax error near unexpected token '{aa}'
> echo $?
2
# 函数的退出状态是最后执行的命令的退出状态
> funr () { echo; return 6; }
> funr; echo $?
# echo 打印的空行
6 # return 6 是函数中最后执行的命令
表达式: 使用 ((...)) 或 let 修饰的表达式的退出状态取决于表达式的值, 如果表达式的值为 0 则退出状态为 1 ; 如果表达式的值为非零, 则退出状态为 0 .
> let 0+0; echo $? 1 # 表达式值为零 > ((7-5)); echo $? 0 # 表达式值非零
命令列表: 用 ; , & , && , || 连接命令被称为命令列表, 其中用 && 和 || 连接的命令使用左关联( left associativity )模式执行列表中的命令. 整个命令列表的退出状态为最后一条命令的退出状态. 此外, $( LISTS ) 以及流程控制结构如: for , while 等的返回状态也是结构中的命令列表的退出状态.
# 功能: 能ping通baidu.com则输出 `baidu.com is up` , 否则输出 `baidu.com is down` 。 > ping -c1 baidu.com &> /dev/null && echo 'baidu.com is up' || echo 'baidu.com is down' baidu.com is down > echo $? 0 # 无论是否能 ping 通, 命令列表的退出状态都等于最后一条命令的退出状态










