【问题标题】:bash: `set -e` does not work when used in if-expression?bash:在 if 表达式中使用时,`set -e` 不起作用?
【发布时间】:2020-05-19 00:22:53
【问题描述】:

看看这个小脚本:

#!/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 $?

我正在尝试执行 here 的建议(不要错过引入子 shell 的额外括号),但我没有单独执行函数(在我的情况下为 do_something),而是与 if 一起执行-表达式。

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

谁能给我解释一下?

【问题讨论】:

  • 除了以这种方式记录它(正如 Simon Doppler 解释的那样)之外,如果 -e 也会在 if 中中止,那将适得其反。请注意,if foo; then ....; else ....; fi 的语义是执行 then 部分,如果 foo 返回零退出代码,则执行 else 部分,如果它返回非零退出代码。如果set -e 会在调用foo 时中止脚本,则else 部分永远不会有机会被执行。

标签: bash if-statement subshell


【解决方案1】:

这是预期的,并在Bash Reference Manual 中进行了描述。

-e

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

[...]

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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2016-08-17
  • 2021-02-05
  • 2011-01-23
  • 2015-05-08
  • 2016-06-18
  • 2014-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多