提问人:Seriously 提问时间:8/23/2023 最后编辑:Charles DuffySeriously 更新时间:10/9/2023 访问量:67
我可以在 bash 中使 [ 语法错误吗 if 语句导致 shell 退出并出现错误?
Can I make bad [ syntax in a bash if statement cause the shell to exit with an error?
问:
请考虑以下代码:bash
if [ "$a" = "foo"]
then
echo "TRUE"
fi
echo $?
我们得到:
bash: [: missing `]'
0
所以基本上,if 中的测试由于拼写错误(和 之间没有空格)而失败,但整个的退出代码仍然是 aka。成功。"foo"
]
if
0
这个答案解释了为什么退出代码是(我们得到的退出代码是因为什么都没有)。0
if
0
true
到目前为止一切顺利,但这种行为非常危险,因为它可能导致静默错误。有没有办法重写条件,或更改任何设置,使这样的拼写错误触发脚本 / 的非零退出?bash
ìf
答:
if
不区分失败的不同原因。但是,它会根据条件是否失败或存在其他错误来设置不同的退出状态。退出状态将是当条件失败时,错误将大于 1。[
1
因此,您可以明确检查以区分:$?
[ "$a" = "foo"] 2>/dev/null
case $? in
0) echo "TRUE" ;;
1) ;;
*) (exit 1) ;;
esac
echo $? # prints 1
评论
/dev/null
是的,有一种方法可以重写条件:不要使用 [
.
#!/bin/bash -e
if [[ "$a" = "foo"]]
then
echo "TRUE"
fi
echo "REACHED"
正确结果:
yourscript: line 1: syntax error in conditional expression
您可以在 https://ideone.com/ZH1Znb 上看到这一点
或者,您可以检查退出状态:
#!/bin/bash -e
# using legacy ksh syntax because some versions of bash are picky
# about function names with POSIX-y syntax; in new bash, though,
# this also works with `[() {` as the first line.
function [ {
builtin [ "$@" || {
rc=$?
case $rc in
0|1) return $?;;
*) echo "ERROR: Bad test syntax" >&2; exit "$rc";;
esac
}
}
if [ "$a" = foo]
then
echo "TRUE"
fi
echo "REACHED"
但这显然是一种可怕的可憎之物。
请注意,虽然上面的例子使用了 ,但这个功能有严重的缺陷,我强烈建议不要使用它。set -e
这实际上不是语句的语法错误,而是命令的语法错误。由于找不到结束参数,该命令失败。if
[
]
所以你在这里所拥有的相当于:
if false; then
echo "TRUE"
fi
测试命令的失败终止状态不会传播到 。if
你只需要一个:else
if command_that_fails_for_any_reason ; then
echo "okay"
else
false
fi
现在,这将导致命令处于失败终止状态,因此脚本将进入模式。false
set -e
如果 test 命令的失败状态传播到 ,则意味着无法阻止脚本在模式下终止。if
if
set -e
在以下示例中,如果失败,脚本将死亡,尽管脚本对其终止状态做出反应。checked_command
set -e
unchecked_command # this will terminate the script if it fails
if checked_command ; then # the script is testing this one
: ...
fi
我们可以争辩说,这里的错误处理是不完整的,因为它只是针对成功的案例进行测试。然而,根据 shell 语言和功能的设计,如果脚本测试终止状态,则认为它已承担全部责任。if
set -e
在以下情况下,让剧本保释会很烦人:
if grep -s pattern /some/file ; then
: # react to pattern being found in file
fi
评论
[
if
if
无法区分由于语法错误或条件为 false 而失败。[
[
[
/usr/bin/[
[
[[
[
[[
[[
[[
[