什么是$? (美元问号)variables在shell脚本?

我正在学习shell脚本,我需要了解别人的代码。 什么是$? variables保持? 我不能谷歌search答案,因为他们阻止标点符号。

$? 用于查找上次执行的命令的返回值。 在shell中尝试以下操作:

 ls somefile echo $? 

如果somefile存在(不pipe它是文件还是目录),你将得到ls命令引发的返回值,它应该是0 (默认为“success”返回值)。 如果它不存在,你应该得到一个不是0的数字。确切的数字取决于程序。

对于许多程序,您可以在相应的手册页中find数字及其含义。 这些通常会被描述为“退出状态”,并可能有自己的部分。

这是上次执行的函数/程序/命令的退出状态。 参考:

  • 退出/退出状态@ tldp.org
  • 特殊的Shellvariables@ tldp.org
  • 特殊字符@ tlpd.org

先前执行的进程的返回值。

10.4获取程序的返回值

在bash中,程序的返回值存储在一个名为$?的特殊variables中。

这说明了如何捕获程序的返回值,我假设目录dada不存在。 (这也是由麦克build议)

  #!/bin/bash cd /dada &> /dev/null echo rv: $? cd $(pwd) &> /dev/null echo rv: $? 

有关更多细节,请参阅Bash编程手册 。

$? 是上次执行的命令的结果(退出代码)。

最小的C例子

要了解$? ,你首先必须了解进程退出状态的概念。

在Linux中:

  • 当进程调用exit系统调用时,即使进程死亡,内核也会将传递给系统调用的值存储起来。

    退出系统调用由exit() ANSI C函数调用,间接从main return

  • 通常用fork + exec调用退出subprocess(Bash)的进程可以通过wait系统调用来检索subprocess的退出状态

考虑Bash代码:

 $ false $ echo $? 1 

C“等价物”是:

false.c:

 #include <stdlib.h> /* exit */ int main() { exit(1); } 

bash.c:

 #include <unistd.h> /* execl */ #include <stdlib.h> /* fork */ #include <sys/wait.h> /* wait, WEXITSTATUS */ #include <stdio.h> /* printf */ int main() { 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)); } 

在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

? 扩展到最近pipe道的小数退出状态(请参阅pipe道)。

man bash “特殊参数”:

shell专门处理几个参数。 这些参数只能被引用; 不允许分配给他们。 […]

? 扩展到最近执行的前台pipe道的退出状态。

ANSI C和POSIX则build议:

  • 0表示程序成功

  • 其他值:程序失败了。

    确切的值可以指示失败的types。

    ANSI C没有定义任何vaues的含义,而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 ]它的参数。

它是上次执行的命令的返回错误代码。 0 =成功

$? 是一个命令的退出状态,以便您可以菊花链连接一系列命令。

 command1 && command2 && command3 

command2将运行,如果command1's $? 产生一个success (0)command3将执行,如果$? command2success

最后一个命令的退出码运行。

如果使用“set -e”,那么它非常适合在脚本退出的情况下进行debugging。 例如,把“echo $?” 在导致它退出并查看返回的错误值的命令之后。