我看到here测试是否$?是零(成功)或其他东西(失败)是反模式,但我无法在其他任何地方找到它。
坚持Wikipedia的反模式的定义:"反模式(或反模式)是对反复出现的问题的常见反应,这种反复出现的问题通常是无效的,并且可能会产生高度适得其反的风险。 #34;为什么这会是反模式?
答案 0 :(得分:10)
这是一个反模式,因为如果您根本不需要记录退出状态,它会引入不存在的复杂性。
if your_command; then ...
比
更容易出错your_command
if [ "$?" -eq 0 ]; then ...
有关可能出错的事情的示例:请考虑添加traps,甚至添加新的echo
语句以进行调试,修改$?
。对于读者来说,运行your_command
的单独行不能在不改变逻辑流的情况下添加任何内容,这在视觉上并不明显。
那是:
your_command
echo "Finished running your_command" >&2
if [ "$?" -eq 0 ]; then ...
...正在检查 echo ,而不是实际的命令。
因此,如果你真的做需要以比它的值是否为零的更精细的方式处理退出状态,你应该在同一行收集它:
# whitelisting a nonzero value for an example of when "if your_command" won't do.
your_command; your_command_retval=$?
echo "Finished running your_command" >&2 ## now, adding more logging won't break the logic.
case $your_command_retval in
0|2) echo "your_command exited in an acceptable way" >&2;;
*) echo "your_command exited in an unacceptable way" >&2;;
esac
最后:如果您将your_command
括在if
语句中,则会将其标记为已测试,这样您的shell就不会将非零退出状态视为目的set -e
或ERR
陷阱。
因此:
set -e
your_command
if [ "$?" -eq 0 ]; then ...
......永远不会(除了一些困扰set -e
行为的角落案例和警告)以{{1}的任何值到达if
语句除了$?
之外,因为0
会在这种情况下强制退出。相比之下:
set -e
...标记了set -e
if your_command; then ...
经过测试的退出状态,因此不会认为这会导致脚本按your_command
退出。