测试后如何保留最后的退出状态

测试后如何保留最后的退出状态

$?测试后是否可以保持最后一个命令的退出状态 ( ) 不变?

例如,我想做:

command -p sudo ...
[ $? -ne 1 ] && exit $?

最后一个exit $?应该返回 sudo 退出状态,但它总是返回0(测试的退出代码)。

是否可以在没有临时变量的情况下做到这一点?

另一个进一步澄清的例子:

 spd-say "$@"
 [ $? -ne 127 ] && exit $?

在这种情况下,我只想在找到第一个命令时退出(退出代码!= 127)。我想使用实际的spd-say退出代码退出(可能不是 0)。

编辑:我忘了提及,我更喜欢 POSIX 兼容的解决方案,以获得更好的可移植性。

我在脚本中使用此构造,我想为同一命令提供替代方案。例如,参见我的crc32 脚本

临时变量的问题是它们可能会隐藏其他变量,并且为了避免必须使用长名称,这不利于代码的可读性。

答案1

根据实际需求,有多种选项可以可靠地处理退出状态而无需额外开销。

您可以使用变量保存退出状态:

command -p sudo ...
rc=$?
[ "$rc" -ne 1 ] && echo "$rc"

可以直接查看成功或失败:

if  command -p sudo ...
then  echo success
else  echo failure
fi

或者使用case构造来区分退出状态:

command -p sudo ...
case $? in
(1) ... ;;
(127) ... ;;
(*) echo $? ;;
esac

问题中提出的特殊情况:

command -p sudo ...
case $? in (1) :;; (*) echo $?;; esac

所有这些选项的优点是它们符合 POSIX 标准。

(注意:为了便于说明,我使用了echo上面的命令;替换为适当的exit语句以匹配请求的功能。)

答案2

command -p ...
test 1 -ne $? && exit $_

使用$_,它扩展为上一个命令的最后一个参数。

答案3

您可以定义(并使用)一个 shell 函数:

check_exit_status()
{
    [ "$1" -ne 1 ] && exit "$1"
}

然后

command -p sudo ...
check_exit_status "$?"

$?可以说,这是“作弊”,因为它在参数列表中复制了check_exit_status

这可能看起来有点尴尬,事实确实如此。 (当您对问题施加任意约束时,有时会发生这种情况。)这可能看起来不灵活,但事实并非如此。您可以变得check_exit_status更复杂,添加参数来告诉它对退出状态值执行什么测试。

答案4

要回答你的直接问题,不,不可能保持$?不变。这是我怀疑您关注错误问题的情况之一。临时变量是获得您想要的效果的标准且首选的方法。它是如此标准,以至于我建议放弃(或重新考虑)您认为不想使用它的任何原因;我非常怀疑任何其他方法所增加的额外复杂性是否值得。

如果您只是出于简单的好奇心而问,那么答案是否定的。

相关内容