自动退出Bash shell脚本的错误:set +e似乎无法完成工作

4

虽然我知道20年来shell脚本不关心错误,但我仍然对这种默认的粗心大意感到惊讶。即使你明确要求它们不要吞噬错误并遵循“尽早崩溃”原则,事情仍然没有发生。

参考自动退出bash shell脚本出现错误set +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

2
set +e 关闭该选项。 - Benjamin W.
5个回答

6

在shell中,使用减号开启选项(通常与直觉相反),使用加号关闭选项。

即使如此,只有当程序正确返回非零错误状态时,set -e选项才能起作用。

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

运行apt命令后,请验证其返回状态(例如使用echo $?)。如果返回值为非零,set -e应该可以正常工作。


6
我猜您只是在使用 set +e 替换了 set -e,或者反之亦然。 如果您只是这样做:
#!/bin/bash -vx
set -e
apt-get install nonexisting1
apt-get install nonexisting2
set +e

当第一行结束后,应该停止运行。


1
为什么你先在脚本中设置了“+e”?
这是我的示例:
#!/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

注意:在脚本结尾不需要设置“+e”。

0

对于像你的四行脚本这样的脚本,假设apt-get在出现错误时会退出并返回非零退出代码,那么使用set -e是合理的。

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

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


0
set -e的作用是有效的,但在if语句中不起作用。看看这个例子:
#!/bin/bash -xv

set -e
+ set -e

if ["$DIR" == "somedirectory"]; then
    echo "directory match"
fi
+ '[' == 'somedirectory]'
./test.sh: line 5: [: missing `]'          <= error

echo "bla 1"
+ echo 'bla 1'
bla 1
echo "bla 2"
+ echo 'bla 2'
bla 2

看到第5行有语法问题,[]之间应该有空格。
# this
if ["$DIR" == "somedirectory"]; then

# should be
if [ "$DIR" == "somedirectory" ]; then

即使存在set -e,bash脚本continue ...出于某种原因
解释:http://mywiki.wooledge.org/BashFAQ/105

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接