什么是$? (美元问号)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
将执行,如果$?
command2
将success
最后一个命令的退出码运行。
如果使用“set -e”,那么它非常适合在脚本退出的情况下进行debugging。 例如,把“echo $?” 在导致它退出并查看返回的错误值的命令之后。