【问题标题】:What is the $? (dollar question mark) variable in shell scripting? [duplicate]什么是美元? (美元问号)shell 脚本中的变量? [复制]
【发布时间】:2011-10-13 15:38:12
【问题描述】:

我正在尝试学习 shell 脚本,我需要了解别人的代码。 $? 变量保持是什么?我无法通过 Google 搜索答案,因为它们会屏蔽标点符号。

【问题讨论】:

  • 一个好的谷歌搜索结果是“bash 美元问号”
  • SymbolHound 适用于涉及特殊字符的搜索。示例:symbolhound.com/?q=%24%3F
  • info bash 也可以,但不幸的是你不能只搜索“$?”,因为文档省略了$。转到“特殊参数”部分(3.4.2 版本 4.2)或搜索反引号-\$'(您必须转义 ?,因为搜索词是正则表达式)。 (我确信有一种方法可以在评论中添加文字反引号。)
  • 谷歌搜索“bash 美元问号”的那一刻将这个 SO 问题作为第一个结果。不要怪我们。
  • @KeithThompson 你现在可能已经知道了,但是你可以使用\` (so you end up writing \\`` 来获得反引号)(以及\\\\\\` 来获得我刚刚写的内容)

标签: shell scripting


【解决方案1】:

最后执行的命令返回的错误码。 0 = 成功

【讨论】:

    【解决方案2】:

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

    10.4 获取程序的返回值

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

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

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

    更多详情请见Bash Programming Manual

    【讨论】:

    • 有那么一瞬间,我以为rv: 是某种老式的选项列表,但结果却是被回显的文本。
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      即最后执行的函数/程序/命令的退出状态。参考:

      【讨论】:

        【解决方案5】:

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

        ls somefile
        echo $?
        

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

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

        【讨论】:

        • 不仅仅是错误代码。是任意命令返回的状态码。
        • 如果文件不存在,返回值为2
        • 如果找不到命令 127 返回
        • 所以man $? 是您获取退出状态的朋友。调用 ((1==2));echo $? 在 bash 中返回 1。
        【解决方案6】:

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

        【讨论】:

          【解决方案7】:

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

          【讨论】:

            【解决方案8】:

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

            示例

            command1 && command2 && command3
            

            command2 将在 command1's $? 产生 success (0) 时运行,如果 command3command2 将产生 successcommand3 将执行

            【讨论】:

              【解决方案9】:

              最小的 POSIX C 退出状态示例

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

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

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

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

              考虑一下 Bash 代码:

              $ false
              $ echo $?
              1
              

              C 的“等价物”是:

              假.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“特殊参数”:

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

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

              ANSI C 和 POSIX 建议:

              • 0 表示程序成功

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

                确切的值可以指示失败的类型。

                ANSI C 没有定义任何值的含义,POSIX 指定大于 125 的值:What is the meaning of "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 ] 它的参数,另请参阅:Difference between single and double square brackets in Bash

              【讨论】:

                猜你喜欢
                • 2011-07-06
                • 2014-11-06
                • 2011-11-07
                • 2013-08-30
                • 2014-02-01
                • 1970-01-01
                • 2014-04-12
                • 1970-01-01
                • 2012-09-05
                相关资源
                最近更新 更多