从错误上自动退出bash shell脚本:set + e似乎没有完成这项工作

时间:2017-01-10 15:18:58

标签: linux bash shell ubuntu error-handling

虽然我知道20年来shell脚本并不关心错误,但我默默地对这种粗心大意感到好笑。即使你明确要求他们不要吞下错误并遵循崩溃早期原则,但仍然没有发生。

参考hereset +e似乎没有做到这一点,这是一个简短的例子:

#!/bin/bash -vx
set +e
apt-get install nonexisting1
apt-get install nonexisting2
set -e

输出:

#!/bin/bash -vx
set +e
+ set +e
apt-get install nonexisting1
+ apt-get install nonexisting1
Reading package lists... Done
Building dependency tree       
Reading state information... Done
E: Unable to locate package nonexisting1  <--- first error, now stop!
apt-get install nonexisting2           <--- why do we continue here?
+ apt-get install nonexisting2
Reading package lists... Done
Building dependency tree       
Reading state information... Done
E: Unable to locate package nonexisting2
set -e
+ set -e

如何确保我的脚本执行所有命令而不会出现错误或立即停止? 我不喜欢在几乎所有行的末尾写|| exit 1

4 个答案:

答案 0 :(得分:5)

shell中的选项(反直觉地)使用减号打开并使用加号关闭。

即便如此,set -e选项仅在程序正确返回非零错误状态时才有效。

虽然apt-get手册说它应该这样做,但其他帖子表明它经常不这样做(见apt-get update exit status)。

验证apt命令运行后的返回状态(例如使用echo $?)。如果它返回非零,set -e应该有效。

答案 1 :(得分:4)

我猜你只是用set + e代替set -e,反之亦然。 如果你只是做

#!/bin/bash -vx
set -e
apt-get install nonexisting1
apt-get install nonexisting2
set +e

它应该在第一行之后停止。

答案 2 :(得分:1)

为什么要设置&#34; + e&#34;脚本的第一个?
这是我的例子:

#!/bin/bash  -xv

set -e 

dskakj

echo "Hello dear" 
apt-get install bash

输出:

#!/bin/bash  -xv

set -e 
+ set -e

dskakj
+ dskakj
./a.sh: line 5: dskakj: command not found

注意:不需要设置&#34; + e&#34;脚本结束。

答案 3 :(得分:0)

对于像你这样的四行脚本,set -e确实感觉合理,假设apt-get确实以非零退出代码退出错误。

然而,关于SO的set -e的大量讨论表明它不是一种可靠的错误处理技术。 Bash文档证实了这一点。

如果我们希望脚本可靠,我们别无选择,只能检查每个命令后的状态变量$?