bash - 为什么要使用 set errexit 而不是 errtrace
问题描述
使用 errtrace 我有更好的结果:
#!/usr/bin/env bash
set -Euxo
trap 'failure ${LINENO} "$BASH_COMMAND"' ERR
...dosomething
failure(){
local lineno=$1
local msg=$2
report="Failed at $lineno: $msg"
email_report
exit 1
}
...bashscript continued
如果我使用 set -e (errexit),
trap 'failure ${LINENO} "$BASH_COMMAND"' EXIT
我的 LINENO 始终为 1,与 errtrace 一样,它显示正确的行号,我只是告诉脚本退出 failure() 函数。因此,似乎我得到了相同的结果,即在捕获错误时停止脚本执行,并报告发生错误的正确行号。
解决方案
根据bash的手册:
陷阱[ -lp ] [[ arg ] sigspec ...]
[…]
如果sigspec为EXIT (0),则在退出 shell 时执行命令arg 。如果sigspec是DEBUG,则命令arg在每个简单命令、for命令、case命令、select命令、每个算术for命令之前执行,并且在第一个命令在 shell 函数中执行之前执行 (...)。有关它对DEBUG陷阱的影响的详细信息,请参阅内置shopt的extdebug选项的描述。如果sigspec是RETURN,每次使用. 或源内置完成执行。
如果sigspec是ERR,则只要简单命令具有非零退出状态,就会执行命令arg ,但须符合以下条件。如果失败的命令是紧跟在while或until关键字之后的命令列表的一部分、if语句中的测试的一部分、在&&或||中执行的命令的一部分,则不会执行ERR陷阱。列表,或者如果命令的返回值通过! . 这些与errexit选项遵循的条件相同。
进入 shell 时忽略的信号不能被捕获、重置或列出。未被忽略的捕获信号在创建时会在子shell 或子shell 环境中重置为其原始值。如果任何sigspec无效,则返回状态为 false;否则陷阱返回真。
设置-e
[…] ERR上的陷阱(如果设置)在 shell 退出之前执行。此选项分别适用于 shell 环境和每个子 shell 环境 (...),并可能导致子 shell 在执行子 shell 中的所有命令之前退出。
退出[n]
[…]在 shell 终止之前执行EXIT上的陷阱。
推荐阅读
- php - 如何停止深度搜索 PHP 中的递归?
- google-apps-script - 在 GAS 中单击 _self 目标链接两次?
- c++ - BOOST_DATA_TEST_CASE 是否总是需要样品的可打印性?
- javascript - 如何访问 img 值?javascript
- python - 比较两个文件夹,返回不同文件的完整路径
- reactjs - ReactJS-在发送到子组件时执行功能
- web3 - 如何使用@ledgerhq/logs?
- arrays - 在 MongoDB 中删除数组中的对象
- iterm2 - 有没有办法更改键盘快捷键以终止 iterm2 中的进程(crtl + c)
- c# - C#读取dll返回值