set -e 不尊重逻辑非
set -e does not respect logical not
在几个 shell 秒后,逻辑非 (!) 将 "invert" 程序的 return 代码。
然而,在带有 set -e
的 shell 脚本中,逻辑 not 似乎导致程序实际上永远不会失败。为什么是这样?
在 bash
、zsh
和 ksh
中进行了测试,结果相同。
$ 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
这是指定的行为。来自 Bash Manual
The shell does not exit if the command that fails is part of the command list immediately following a while
or until
keyword, part of the test in an if
statement, part of any command executed in a &&
or ||
list except the command following the final &&
or ||
, any command in a pipeline but the last, or if the command’s return status is being inverted with !
.
这也是specified by POSIX(斜体是我的):
The -e
setting shall be ignored when executing the compound list following the while
, until
, if
, or elif
reserved word, a pipeline beginning with the !
reserved word, or any command of an AND-OR list other than the last.
在几个 shell 秒后,逻辑非 (!) 将 "invert" 程序的 return 代码。
然而,在带有 set -e
的 shell 脚本中,逻辑 not 似乎导致程序实际上永远不会失败。为什么是这样?
在 bash
、zsh
和 ksh
中进行了测试,结果相同。
$ 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
这是指定的行为。来自 Bash Manual
The shell does not exit if the command that fails is part of the command list immediately following a
while
oruntil
keyword, part of the test in anif
statement, part of any command executed in a&&
or||
list except the command following the final&&
or||
, any command in a pipeline but the last, or if the command’s return status is being inverted with!
.
这也是specified by POSIX(斜体是我的):
The
-e
setting shall be ignored when executing the compound list following thewhile
,until
,if
, orelif
reserved word, a pipeline beginning with the!
reserved word, or any command of an AND-OR list other than the last.