![为什么 Unix 命令在 Shell 中以非零值退出,并在 bash if 条件中使用时计算结果为 True?](https://linux22.com/image/200015/%E4%B8%BA%E4%BB%80%E4%B9%88%20Unix%20%E5%91%BD%E4%BB%A4%E5%9C%A8%20Shell%20%E4%B8%AD%E4%BB%A5%E9%9D%9E%E9%9B%B6%E5%80%BC%E9%80%80%E5%87%BA%EF%BC%8C%E5%B9%B6%E5%9C%A8%20bash%20if%20%E6%9D%A1%E4%BB%B6%E4%B8%AD%E4%BD%BF%E7%94%A8%E6%97%B6%E8%AE%A1%E7%AE%97%E7%BB%93%E6%9E%9C%E4%B8%BA%20True%EF%BC%9F.png)
该命令patch -R -p0 -s -f --dry-run < abc.patch
失败,退出代码为 1,并打印 patch 命令的错误消息,但当在 if 条件中与否定一起使用时,它会通过(即打印 Pass),下面是代码
if ! patch -R -p0 -s -f --dry-run < abc.patch; then
echo "Pass"
fi
我尝试了什么?我重定向了字符串 dev/null 结果没有变化
请帮我理解这里出了什么问题?
答案1
patch
由于您否定了for语句的退出状态if
,因此该if
语句可以读作“如果patch
失败,则输出字符串Pass
”。
该if
语句测试给定命令是否成功(真的) 或失败 (错误的)。如果您愿意,您可以记住这一点并忘记此答案中的其余部分。
当命令失败时,其退出状态不为零,可能允许更仔细地检查失败的原因。如果实用程序为返回的实际值指定了任何含义(例如,curl
请rsync
参阅其手册的最后部分),脚本可以选择适当地处理错误。
如果该命令的退出状态为零,则它向 shell 发出该实用程序已成功完成的信号。
退出状态更多的是“错误代码”而不是“布尔值”或“真或假”。 true/false 布尔测试是通过if
测试退出状态的语句在内部执行的,以查看实用程序是否存在故障情况。如果不是(退出状态为零),则测试为真的,即实用程序没有失败。
答案2
你显然想说“除非X错了,就做Y”,用否定的“如果”来表达“除非”,最后有效地否定了“错误”,所以你的“如果”成功了,如果(并且只有当)X 是错误的(参见@他们的答案)。这与退出代码无关,只是与否定的复杂性有关。