如何在Bash中测试命令的非零退出状态?

15

我有一个脚本,它检查以下函数的退出状态:

function is_git_repository {                                                    
    git branch &> /dev/null                                                     
}  

如果你在一个 Git 仓库中,它将返回 0,否则返回 128

我测试返回值是否为 0 没有问题;以下代码按预期工作:

if is_git_repository ; then 
    echo you are in a git repo
else 
    echo you are NOT in a git repo
fi

但是当我试图测试一个退出状态是否为任何值“0”之外的时候,我遇到了问题。我尝试了以下方法,但它们都不起作用:

  1. if [[ "$(is_git_repository)" != "0" ]] ; ... 总是被评估为真 (链接)
  2. if [[ "$(is_git_repository)" -ne "0" ]] ; ... 总是被评估为假
  3. if [[ "$(is_git_repository)" != 0 ]] ; ... 总是被评估为真
  4. if [[ "$(is_git_repository)" -ne 0 ]] ; ... 总是被评估为假
  5. if ! "$(is_git_repository)" ; ... 总是被评估为真
  6. if !is_git_repository ; ... 只是将命令原样返回给我,但没有感叹号(什么鬼?)

在if语句中检查命令的非零退出状态的正确方法是什么?


4
你似乎在寻找$?。 - devnull
你链接的“源”既不是该问题的被接受答案,也不是得票最高的答案。 - glenn jackman
2个回答

16

我很快就弄清楚了,if ! is_git_repository ; then ... 能够如预期地工作(请参考if介绍下的7.1.2.1 测试退出状态),但是为什么呢? 我本来期望#1至少能工作,但我不知道它为什么不能。

另外,#6怎么了?!


4
当你输入 "$(is_git_repository)" 时,你会得到该命令的标准输出,而不是退出状态码。你重定向了stdout和stderr,因此它们始终为空字符串,而空字符串永远不等于字符串"0"。bash对空格很敏感,所以 "!" 必须单独写。如@devnull所提到的,如果想要退出状态码,需要使用 $? 变量。 - glenn jackman
@glennjackman 谢谢!这解释清楚了。那么带有“-ne”的呢?它们为什么与带有“!=”的不同?(即,为什么使用“-ne”时空字符串等于“0”/0,但使用“!=”时不等于“0”/0?) - 3cheesewheel
1
手册中的shell arithmetic部分指出:“空值计算为0”。 - glenn jackman
#6 是历史扩展,只会在交互式 shell 中发生。它会打印出与您的历史记录匹配的命令,然后运行它。 - that other guy

6
考虑使用布尔运算符代替if语句:
is_git_repository || echo you are NOT in a git repo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接