什么是$? shell脚本中的(美元问号)变量?

时间:2011-07-26 18:08:15

标签: shell scripting

我正在尝试学习shell脚本,我需要了解其他人的代码。什么是$?变量保持?我不能谷歌搜索答案,因为他们阻止标点字符。

9 个答案:

答案 0 :(得分:218)

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

ls somefile
echo $?

如果somefile存在(无论它是文件还是目录),您将获得ls命令抛出的返回值,该命令应为0(默认为“成功”返回值)。如果它不存在,你应该得到一个0以外的数字。确切的数字取决于程序。

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

答案 1 :(得分:45)

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

答案 2 :(得分:18)

先前执行过程的返回值。

  

10.4获取程序的返回值

     

在bash中,程序的返回值存储在一个特殊变量中   叫$?。

     

这说明了如何捕获程序的返回值,I   假设目录dada不存在。 (这也是   mike建议

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

有关详细信息,请参阅Bash Programming Manual

答案 3 :(得分:9)

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

答案 4 :(得分:8)

最小C示例

要理解$?,您必须首先了解流程退出状态的概念。

在Linux中:

  • 当进程调用exit系统调用时,即使进程终止,内核也会存储传递给系统调用的值。

    退出系统调用由exit() ANSI C函数调用,并且当您从return执行main时间接调用。

  • 调用退出子进程(Bash)的进程(通常使用fork + exec)可以使用wait系统调用<检索子进程的退出状态< / p>

考虑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

  

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

man bash“特殊参数”:

  

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

     

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

ANSI C和POSIX然后建议:

  • 0表示该计划已成功

  • 其他值:程序以某种方式失败。

    确切的值可能表示失败的类型。

    ANSI C未定义任何vaues的含义,POSIX指定大于125的值:I never really understood: what is 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 ]它的参数,另见:What is the difference between single and double square brackets in Bash?

答案 5 :(得分:4)

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

答案 6 :(得分:4)

$?是命令的退出状态,这样您就可以菊花链式连接一系列命令。

示例

command1 && command2 && command3

command2将在command1's $?产生success (0)时生效,如果command3 $?将产生command2将会执行success一个$x=5; echo $x."".++$x."".$x++;

答案 7 :(得分:2)

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

答案 8 :(得分:2)

如果在使用set -e的情况下退出脚本,它非常适合调试。例如,将echo $?放在导致它退出的命令之后,并查看返回的错误值。