imz*_*hev 16 bash shell-script error-handling
为了安全起见,如果遇到语法错误,我希望 bash 中止脚本的执行。
令我惊讶的是,我无法做到这一点。(set -e
还不够。)示例:
#!/bin/bash
# Do exit on any error:
set -e
readonly a=(1 2)
# A syntax error is here:
if (( "${a[#]}" == 2 )); then
echo ok
else
echo not ok
fi
echo status $?
echo 'Bad: has not aborted execution on syntax error!'
Run Code Online (Sandbox Code Playgroud)
结果(bash-3.2.39 或 bash-3.2.51):
$ ./sh-on-syntax-err
./sh-on-syntax-err: line 10: #: syntax error: operand expected (error token is "#")
status 1
Bad: has not aborted execution on syntax error!
$
Run Code Online (Sandbox Code Playgroud)
好吧,我们不能$?
在每个语句之后检查以捕获语法错误。
(我期望从一种明智的编程语言中获得这种安全的行为......也许这必须作为一个错误/希望报告给 bash 开发人员)
if
没什么区别。删除if
:
#!/bin/bash
set -e # exit on any error
readonly a=(1 2)
# A syntax error is here:
(( "${a[#]}" == 2 ))
echo status $?
echo 'Bad: has not aborted execution on syntax error!'
Run Code Online (Sandbox Code Playgroud)
结果:
$ ./sh-on-syntax-err
./sh-on-syntax-err: line 6: #: syntax error: operand expected (error token is "#")
status 1
Bad: has not aborted execution on syntax error!
$
Run Code Online (Sandbox Code Playgroud)
也许,它与http://mywiki.wooledge.org/BashFAQ/105 中的练习 2 相关,并且与(( ))
. 但我发现在语法错误后继续执行仍然不合理。
(( ))
没有区别!即使没有算术测试,它的表现也很糟糕!只是一个简单的基本脚本:
#!/bin/bash
set -e # exit on any error
readonly a=(1 2)
# A syntax error is here:
echo "${a[#]}"
echo status $?
echo 'Bad: has not aborted execution on syntax error!'
Run Code Online (Sandbox Code Playgroud)
结果:
$ ./sh-on-syntax-err
./sh-on-syntax-err: line 6: #: syntax error: operand expected (error token is "#")
status 1
Bad: has not aborted execution on syntax error!
$
Run Code Online (Sandbox Code Playgroud)
将整个包装成一个函数似乎可以解决问题:
#!/bin/bash -e
main () {
readonly a=(1 2)
# A syntax error is here:
if (( "${a[#]}" == 2 )); then
echo ok
else
echo not ok
fi
echo status $?
echo 'Bad: has not aborted execution on syntax error!'
}
main "$@"
Run Code Online (Sandbox Code Playgroud)
结果:
$ ./sh-on-syntax-err
$ ./sh-on-syntax-err line 6: #: syntax error: operand expected (error token is "#")
$
Run Code Online (Sandbox Code Playgroud)
虽然我不知道为什么 - 也许其他人可以解释?
您可能对 的真正含义产生了误导set -e
。仔细阅读help set
节目的输出:
-e Exit immediately if a command exits with a non-zero status.
Run Code Online (Sandbox Code Playgroud)
非零命令-e
的退出状态也是如此,而不是脚本中的语法错误。
一般来说,使用 被认为是不好的做法set -e
,因为所有错误(即命令的所有非零返回)都应该由脚本巧妙地处理(想想强大的脚本,而不是那些在您输入带有空格或以连字符开头)。
根据语法错误的类型,脚本甚至可能根本不会执行。我对 bash 的了解不够,无法确切说明哪类语法错误(如果可以分类的话)可能会导致脚本立即中止。也许一些 Bash 大师会加入并澄清一切。
我只希望我澄清了set -e
声明!
关于你的愿望:
我期望从一种明智的编程语言中获得这种安全的行为......也许这必须作为一个错误/愿望报告给 bash 开发人员
答案肯定是否定的!正如您所观察到的(set -e
没有您所期望的响应)实际上有很好的记录。
你可以通过放置类似的东西来让脚本自我检查
bash -n "$0"
Run Code Online (Sandbox Code Playgroud)
在脚本顶部附近——set -e
在任何重要代码段之后但之前。
我不得不说这感觉不是很健壮,但如果它对你有用,也许它是可以接受的。
归档时间: |
|
查看次数: |
11578 次 |
最近记录: |