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

Dav*_*der 238 shell scripting

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

poo*_*raj 235

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

ls somefile
echo $?
Run Code Online (Sandbox Code Playgroud)

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

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

  • 不只是错误代码.它是任何命令的返回状态代码. (13认同)
  • 如果文件不存在,则返回值为"2" (10认同)

Dor*_*Dor 45

这是最后执行的函数/程序/命令的退出状态.参考:


小智 18

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

10.4获取程序的返回值

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

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

        #!/bin/bash
        cd /dada &> /dev/null
        echo rv: $?
        cd $(pwd) &> /dev/null
        echo rv: $?
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅Bash编程手册.


Cir*_*四事件 11

最小C的例子

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

在Linux中:

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

    退出系统调用由exit()ANSI C函数调用,并在执行return时间接调用main.

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

考虑Bash代码:

$ false
$ echo $?
1
Run Code Online (Sandbox Code Playgroud)

C"等价物"是:

false.c:

#include <stdlib.h> /* exit */

int main() {
    exit(1);
}
Run Code Online (Sandbox Code Playgroud)

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));
}
Run Code Online (Sandbox Code Playgroud)

在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的值: 我从未真正理解:什么是POSIX?

Bash使用退出状态 if

在Bash中,我们经常$?隐式使用退出状态来控制if语句,如:

if true; then
  :
fi
Run Code Online (Sandbox Code Playgroud)

哪个true是只返回0的程序.

以上相当于:

true
result=$?
if [ $result = 0 ]; then
  :
fi
Run Code Online (Sandbox Code Playgroud)

并在:

if [ 1 = 1 ]; then
  :
fi
Run Code Online (Sandbox Code Playgroud)

[只是一个具有奇怪名称的程序(和Bash内置的行为类似)1 = 1 ]及其参数,另请参阅:Bash中单方括号和双方括号之间的区别是什么?


mar*_*log 9

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


Wul*_*ulf 6

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


小智 5

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

例子

command1 && command2 && command3
Run Code Online (Sandbox Code Playgroud)

command2如果command1's $?产生 a将运行success (0)并且command3如果$?ofcommand2将产生 a 将执行success