bash: `set -e` 在 if 表达式中使用时不起作用?

fra*_*ans 4 bash if-statement subshell

看看这个小脚本:

#!/bin/bash

function do_something() {(
    set -e

    mkdir "/opt/some_folder"                                     # <== returns 1 -> abort?
    echo "mkdir returned $?"                                     # <== sets $0 to 0 again

    rsync $( readlink -f "${BASH_SOURCE[0]}" ) /opt/some_folder/ # <== returns 23 -> abort?
    echo "rsync returned $?"                                     # <== sets $0 to 0 again
)}


# here  every command inside `do_something` will be executed - regardless of errors
echo "run do_something in if-context.."
if ! do_something ; then
  echo "running do_something did not work"
fi

# here `do_something` aborts on first error
echo "run do_something standalone.."
do_something
echo $?
Run Code Online (Sandbox Code Playgroud)

我试图执行此处建议的操作(不要错过引入子 shell 的额外括号),但我没有do_something单独执行该函数(在我的例子中),而是与 if 表达式一起执行。

现在当我运行if ! do_somethingset -e命令时似乎没有效果。

谁可以给我解释一下这个?

Sim*_*ler 6

这是预期的,并且在Bash 参考手册中进行了描述。

-e

[...]while如果失败的命令是紧跟在or关键字之后的命令列表的一部分、语句until中测试的一部分[...] , 则 shell 不会退出。if

[...]

如果复合命令或 shell 函数在被忽略的上下文中执行-e,则在复合命令或函数体内执行的任何命令都不会受到该-e设置的影响,即使-e已设置并且命令返回失败状态。如果复合命令或 shell 函数在被忽略的-e上下文中执行时设置-e,则在复合命令或包含函数调用的命令完成之前,该设置不会产生任何效果。