Answers:
这是最后执行的命令的退出状态。
例如,该命令true
始终返回状态,0
并且false
始终返回状态1
:
true
echo $? # echoes 0
false
echo $? # echoes 1
从手册中:(可通过调用man bash
shell来实现)
$?
扩展到最近执行的前台管道的退出状态。
按照惯例,退出状态0
表示成功,非零返回状态表示失败。在Wikipedia上了解有关退出状态的 更多信息。
您可以在此在线手册上看到其他类似的特殊变量:https : //www.gnu.org/s/bash/manual/bash.html#Special-Parameters
$
和?
是两个不同的参数,$?
不会出现在bash(1)联机帮助页中。
$?
返回最后执行的命令的退出值。echo $?
在控制台上打印该值。零表示成功执行,而非零值映射到各种失败原因。
因此,在编写脚本时;我倾向于使用以下语法
if [ $? -eq 0 ]; then
# do something
else
# do something else
fi
比较将在等于0
或不等于上进行0
。
**根据注释进行更新:理想情况下,不应使用以上代码块进行比较,请参阅@tripleee注释和说明。
cmd; if [ $? -eq 0 ]; then
应该重构为if cmd; then
。非常目的的if
(并且在外壳的其他流程控制语句)是运行一个命令并检查其退出状态。
if cmd;
在某些情况下可能不是很可读,特别是在cmd引用另一个脚本时。
[ 1 ]
并且[ 0 ]
都是真实的;[
没有运算符的情况下,将检查参数是否为非空字符串。
vendor/bin/drush status bootstrap | grep -q $(vendor/bin/drush php-eval 'if (function_exists("t")) echo t("Successful");') &> /dev/null;
。如果我不得不将其放在一行中,if [ ... ]
那将是非常难以理解的。我计划将该行的输出存储到变量中,以便if [ $drupal_installed -eq 0 ]
稍后再说。
回声$?-给出最近执行的命令的退出状态。此退出状态很可能是一个数字,表示零,表示成功;任何非零值,表示失败
? -这是bash中的一个特殊参数/变量。
$?-它给出了存储在变量“?”中的值。
BASH中一些类似的特殊参数是1,2,*,#(通常在echo命令中显示为$ 1,$ 2,$ *,$#等)。
最小POSIX C退出状态示例
要理解$?
,您必须首先了解POSIX定义的进程退出状态的概念。在Linux中:
当进程调用exit
系统调用时,内核会存储传递给系统调用的值(int
即使进程死亡也会)。
退出系统调用由exit()
ANSI C函数调用,而return
从中调用则间接调用main
。
经常使用fork
+ 调用退出子进程(Bash)的进程exec
可以通过wait
系统调用检索子进程的退出状态
考虑一下Bash代码:
$ false
$ echo $?
1
C的“等效”为:
错误的
#include <stdlib.h> /* exit */
int main(void) {
exit(1);
}
bash.c
#include <unistd.h> /* execl */
#include <stdlib.h> /* fork */
#include <sys/wait.h> /* wait, WEXITSTATUS */
#include <stdio.h> /* printf */
int main(void) {
if (fork() == 0) {
/* Call false. */
execl("./false", "./false", (char *)NULL);
}
int status;
/* Wait for a child to finish. */
wait(&status);
/* Status encodes multiple fields,
* we need WEXITSTATUS to get the exit status:
* http://stackoverflow.com/questions/3659616/returning-exit-code-from-child
**/
printf("$? = %d\n", WEXITSTATUS(status));
}
编译并运行:
g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o bash bash.c
g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o false false.c
./bash
输出:
$? = 1
在Bash中,当您按Enter键时,将发生如上所示的fork + exec + wait,然后bash设置 $?
为派生进程的退出状态。
注意:对于诸如的内置命令echo
,无需生成进程,而Bash只需设置$?
为0即可模拟外部进程。
标准和文件
POSIX 7 2.5.2“特殊参数” http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_05_02:
?扩展到最新管道的小数退出状态(请参见管道)。
man bash
“特殊参数”:
外壳专门处理几个参数。这些参数只能被引用;不允许分配给他们。[...]
?扩展到最近执行的前台管道的退出状态。
然后,ANSI C和POSIX建议:
0
表示程序成功
其他值:程序因某种原因失败。
确切的值可以指示故障的类型。
ANSI C没有定义任何变量的含义,并且POSIX指定的值大于125: “ POSIX”的含义是什么?
Bash将退出状态用于 if
在Bash中,我们经常$?
隐式使用退出状态来控制if
语句,如下所示:
if true; then
:
fi
true
一个只返回0的程序在哪里?
以上等同于:
true
result=$?
if [ $result = 0 ]; then
:
fi
在:
if [ 1 = 1 ]; then
:
fi
[
只是一个名称很奇怪的程序(以及行为类似于它的Bash内置程序)1 = 1 ]
及其参数,另请参见:Bash中单方括号和双方括号之间的区别
来自http://www.gnu.org/s/bash/manual/bash.html#Special-Parameters
?
Expands to the exit status of the most recently executed foreground pipeline.