什么

echo $?

是指shell编程吗?


这是上次执行命令的退出状态。

例如,命令true总是返回0状态,false总是返回1状态:

true
echo $? # echoes 0
false
echo $? # echoes 1

从手册:(通过在shell中调用man bash来访问)

吗?展开到最近执行的前台管道的退出状态。

按照惯例,退出状态为0表示成功,返回状态为非零表示失败。在维基百科上了解更多关于退出状态的信息。

还有其他类似的特殊变量,你可以在这个在线手册上看到:https://www.gnu.org/s/bash/manual/bash.html#Special-Parameters

它是命令的最后一个状态码(退出值)。

从http://www.gnu.org/s/bash/manual/bash.html特殊参数

?
Expands to the exit status of the most recently executed foreground pipeline. 

参见3.4.2特殊参数中的Bash手册:

? —展开到最近执行的前台管道的退出状态。

有点难找,因为它没有列在$?(变量名是“just”?)当然,还可以查看退出状态部分;-)

快乐的编码。

输出上次执行的unix命令的结果

0 implies true
1 implies false

$ ?返回最后执行命令的退出值。echo $ ?在控制台打印该值。0表示执行成功,而非0值则映射为失败的各种原因。

因此当编写脚本时;我倾向于使用以下语法

if [ $? -eq 0 ]; then
 # do something
else
 # do something else
fi

比较是在等于0或不等于0时进行的。

**基于注释的更新:理想情况下,你不应该使用上面的代码块进行比较,参考@tripleee注释和解释。

echo $ ?-给出最近执行的命令的EXIT STATUS。这个EXIT STATUS很可能是一个数字,其中0表示成功,任何非0值表示失败

吗?-这是bash中的一个特殊参数/变量。

$ ?-它给出存储在变量"?"中的值。

BASH中一些类似的特殊参数有1、2、*、#(通常在echo命令中可以看到$1、$2、$*、$#等)。

最小POSIX C退出状态示例

要理解$?,您必须首先理解由POSIX定义的进程退出状态的概念。在Linux中:

当进程调用exit系统调用时,内核存储传递给系统调用的值(int),即使在进程死亡后也是如此。 exit系统调用由exit() ANSI C函数调用,并且在从main返回时间接调用。 调用退出子进程的进程(Bash),通常使用fork + exec,可以通过等待系统调用检索子进程的退出状态

考虑一下Bash代码:

$ false
$ echo $?
1

C“等价物”是:

false.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设置$?到fork进程的退出状态。

注意:对于像echo这样的内置命令,不需要生成进程,Bash只需要设置$?为0来模拟外部进程。

标准和文档

POSIX 7 2.5.2特殊参数http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_05_02:

? 展开到最新管道的十进制退出状态(请参阅管道)。

man bash特殊参数:

shell对几个参数进行了特殊处理。这些参数只能被引用;不允许分配给他们。[…] ? 展开到最近执行的前台管道的退出状态。

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中单方括号和双方括号的区别