使用trap
可能有助于编写最干净的bash脚本。
但是我想知道是否存在解决方案以便在以下情况下捕获错误:
GNU bash,版本4.2.45
案例确定
#!/bin/bash
trap 'echo OK i see error at line $LINENO;exit' ERR
unknowncommand
echo "test KO should never reach me"
案例KO
#!/bin/bash
trap 'echo OK i see error at line $LINENO;exit' ERR
unknowncommand && echo "miss the trap"
echo "test KO should never reach me"
&&
使整个句子不是ERR。答案 0 :(得分:6)
您想要评估整个评估的退出状态,而不是尝试短路。一种方法是将整个事物包装在子shell中。例如:
#!/bin/bash
trap 'echo "OK i see error at line $LINENO"; exit' ERR
(unknowncommand && echo "miss the trap")
echo "test KO should never reach me"
这可以按预期工作。结果如下:
$ /tmp/err.sh
/tmp/err.sh: line 3: unknowncommand: command not found
OK i see error at line 3
答案 1 :(得分:1)
根据documentation for 4.2 (recent at the time of this answer)
如果sigspec是ERR,则只要简单命令具有非零退出状态,就会执行命令arg,具体取决于以下条件。如果失败的命令是紧跟在until或while关键字之后的命令列表的一部分,则执行ERR陷阱,在if或elif保留字之后的测试的一部分,在&&和/或或||列表,或者如果使用!反转命令的返回状态。
解决此问题的一种方法是使用if
语句检查$?
而不是&&
列表的值。
trap 'echo OK i see error at line $LINENO;exit' ERR
unknowncommand
if [ $? -eq 0 ]; then
echo "miss the trap"
fi
echo "test KO should never reach me"
另一个似乎有效的方法是将命令包装在子shell中,尽管文档似乎没有提到为失败的子shell触发ERR
。 (子shell通常不被认为是一个简单的命令,但文档也没有否认它。)子shell的退出状态是最后一行的退出状态,在这种情况下(x && y
)是如果x
失败,则退出状态,否则退出状态为y
。
trap 'echo OK i see error at line $LINENO;exit' ERR
( unknowncommand && echo "miss the trap" )
echo "test KO should never reach me"