set -e不尊重逻辑

时间:2019-08-27 20:39:28

标签: bash shell zsh ksh

在几个shell中,逻辑非(!)将“反转”程序的返回代码。

但是,在带有set -e的shell脚本中,逻辑非似乎导致该程序实际上从未失败。为什么是这样?

bashzshksh中进行了测试,结果相同。

$ cat test.sh 
set -ex

# setup
touch myfile

# observe available files
ls .

# succeeds
ls myfile; echo $?

# this succeeds as expected
! ls notafile; echo $?

# why does this not exit when the return code is clearly non-zero?
! ls myfile; echo $?

# this exits as expected when there is a non-zero return code
ls notafile; echo $?

# becasue we exit just above, this never get executed
echo "test passed"

结果:

bash test.sh 
+ touch myfile
+ ls .
myfile  test.sh
+ ls myfile
myfile
+ echo 0
0
+ ls notafile
ls: cannot access 'notafile': No such file or directory
+ echo 0
0
+ ls myfile
myfile
+ echo 1
1
+ ls notafile
ls: cannot access 'notafile': No such file or directory

2 个答案:

答案 0 :(得分:3)

这是指定的行为。从Bash Manual

  

如果失败的命令是紧随whileuntil关键字(属于if语句中的测试的一部分)之后的命令列表的一部分,则外壳程序不会退出。在&&||列表中执行的任何命令,除了最后一个&&||之后的命令,管道中除最后一个以外的任何命令,或者! 反转了命令的返回状态。

答案 1 :(得分:1)

这也是specified by POSIX(斜体字):

  

在执行 -e while until 设置strong>, if elif 保留字, !开头的管道strong>保留字,或除最后一个以外的任何AND-OR列表命令。