什么是美元? (美元问号)shell 脚本中的变量? [复制]
Posted
技术标签:
【中文标题】什么是美元? (美元问号)shell 脚本中的变量? [复制]【英文标题】:What is the $? (dollar question mark) variable in shell scripting? [duplicate] 【发布时间】:2011-10-13 15:38:12 【问题描述】:我正在尝试学习 shell 脚本,我需要了解别人的代码。 $?
变量保持是什么?我无法通过 Google 搜索答案,因为它们会屏蔽标点符号。
【问题讨论】:
一个好的谷歌搜索结果是“bash 美元问号” SymbolHound 适用于涉及特殊字符的搜索。示例:symbolhound.com/?q=%24%3Finfo bash
也可以,但不幸的是你不能只搜索“$?”,因为文档省略了$
。转到“特殊参数”部分(3.4.2 版本 4.2)或搜索反引号-\$'
(您必须转义 ?
,因为搜索词是正则表达式)。 (我确信有一种方法可以在评论中添加文字反引号。)
谷歌搜索“bash 美元问号”的那一刻将这个 SO 问题作为第一个结果。不要怪我们。
@KeithThompson 你现在可能已经知道了,但是你可以使用\` (so you end up writing
\\`` 来获得反引号)(以及\\\\\\`
来获得我刚刚写的内容)
【参考方案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】:即最后执行的函数/程序/命令的退出状态。参考:
exit / exit status @ tldp.org Special Shell Variables @ tldp.org Special Characters @ tlpd.org【讨论】:
【参考方案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)
时运行,如果 command3
或 command2
将产生 success
则 command3
将执行
【讨论】:
【参考方案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://***.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
【讨论】:
以上是关于什么是美元? (美元问号)shell 脚本中的变量? [复制]的主要内容,如果未能解决你的问题,请参考以下文章