为啥 if [ ...something... ];然后回显“退出状态是$?”总是发出 0?
Posted
技术标签:
【中文标题】为啥 if [ ...something... ];然后回显“退出状态是$?”总是发出 0?【英文标题】:Why does if [ ...something... ]; then echo "Exit status is $?" always emit 0?为什么 if [ ...something... ];然后回显“退出状态是$?”总是发出 0? 【发布时间】:2018-06-27 01:54:17 【问题描述】:在 bash 中输出退出状态的正确方法是什么?据我所知,$?
调用的退出状态对应的是最后执行的命令的状态。
正在处理的脚本对作为参数提供的文件进行了一些条件检查,例如,检查是否有任何文件被命名或文件是否存在。
所以我有这样的条件语句:
if [ $# -eq 0 ] ; then
echo "No file name(s) given! \nExit status=$?"
exit
if [ ! -e "$fName" ] ; then
echo "$fName does not exist! \nExit status=$?"
exit
但是这些返回的退出状态为 0。我什至不完全确定哪些退出代码适用于每种情况,但我认为基于 this 的两个 1 都适用。我应该将 1 硬编码到条件语句中还是更改逻辑以便 unix 输出错误代码?另外,我在上面的例子中得到的 0 是什么命令的退出代码?
【问题讨论】:
顺便说一句,echo
也有退出状态,所以当你到达exit
时,你最后的退出状态是echo
,所以(假设@987654331 @成功写入其输出)exit
的默认行为exit "$?"
将具有exit 0
的效果,无论$?
在echo
运行之前是什么。
另外,我强烈强烈建议避免将 ABS 作为参考;当它不是完全错误的时候,它在其示例中展示不良做法的历史由来已久。 bash-hackers' wiki 和 BashGuide 是更好的来源,当然official manual 也是如此。
除了链接之外,代码中是否有一些看起来不好的做法?
我正在回复链接,但是使用带有反斜杠文字的 echo
是 POSIX 未指定的,并且具有跨 shell(甚至跨运行时配置,例如改变 @ 的状态)的行为987654338@ bash 中的标志);请参阅pubs.opengroup.org/onlinepubs/9699919799/utilities/echo.html 的应用程序使用部分
顺便说一句,就个人而言,我可能会写这些检查更像(( $# )) || echo "ERROR: No file names given!" >&2; exit 1;
(如果我们使用bashisms;否则[ "$#" -eq 0 ] && ...
)和[[ -e $fName ]] || echo "ERROR: Could not find $fName" >&2; exit 1;
(这里,使用[[
而不是@987654343 @ 以获得扩展的语法,使引号变得不必要;再次,一个扩展,但是一个显式的扩展,它在受 ksh 启发的 shell(其中包括 bash 和 zsh )中表现一致)。
【参考方案1】:
在这两种情况下,最后执行的命令是 [
,它以 0 状态(“成功”)退出,让您进入“真实”块。
是的,您需要为exit
命令指定一个非零退出代码。
迂腐的“unix”不输出错误代码:它是运行脚本的shell,以指定的状态退出。
【讨论】:
是的,它是一个命令,而不仅仅是语法。它也被称为test
。在交互式 bash 提示符下,输入 help [
了解详细信息。
我建议从type -a [
开始,这将提供足够的信息来了解下一步是help
(用于shell 内置程序或关键字)还是man
(用于外部命令)。 (有几个命令既是 shell 内置命令又是外部命令;shell 版本在这种情况下实际上是一种性能优化)。
请注意,[[ ]]
和 (( ))
是 shell 语法(在 bash 和其他一些 shell 中),但仍会影响 $?
,就好像它们是命令一样。跨度>
以上是关于为啥 if [ ...something... ];然后回显“退出状态是$?”总是发出 0?的主要内容,如果未能解决你的问题,请参考以下文章
Excel IF -eq“Something”在下一个可用空格中写入
Perl if 语句,If value = nothing do 语句 if value = something do 语句
If you want something, go get it. Period.---献给《阿甘正传》、《当幸福来敲门》