ubuntu 出现错误时自动退出bash shell脚本:set +e似乎不起作用

5us2dqdw  于 2023-10-17  发布在  Shell
关注(0)|答案(5)|浏览(203)

虽然我知道shell脚本不关心错误已经有20年了,但我仍然对这种默认的粗心感到好笑。即使你明确要求他们不要吞下错误,并遵循崩溃早期原则,仍然不会发生。
参考Automatic exit from bash shell script on errorset +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

jvidinwx

jvidinwx1#

shell中的选项(与直觉相反)使用减号打开,使用加号关闭。
即便如此,set -e选项也只有在程序正确返回非零错误状态时才有效。
尽管apt-get手册说它应该这样做,但其他帖子表明它经常不这样做(参见apt-get update exit status)。
验证apt命令运行后的返回状态(例如,使用echo $?)。如果它返回非零值,set -e应该可以工作。

sh7euo9m

sh7euo9m2#

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

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

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

5vf7fwbs

5vf7fwbs3#

为什么你把“+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”。

xqkwcwgp

xqkwcwgp4#

对于像您这样的四行脚本,set -e确实是合理的,假设apt-get确实以非零的错误退出代码退出。
然而,关于SO上set -e的大量讨论表明,它不是一种可靠的错误处理技术。Bash文档证实了这一点。
如果我们希望我们的脚本是可靠的,我们别无选择,只能在每个命令之后检查状态变量$?

yjghlzjz

yjghlzjz5#

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

请注意,line: 5有语法问题,[]之间应该有空格:

# this
if ["$DIR" == "somedirectory"]; then

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

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

相关问题