如何为单个命令禁用 set -e?

Gus*_*ave 49 bash

set -e 命令使 bash 脚本在任何命令返回非零退出代码时立即失败。

  1. 是否有一种简单而优雅的方法可以为脚本中的单个命令禁用此行为?

  2. Bash 参考手册 ( http://www.gnu.org/software/bash/manual/bashref.html ) 中记录了此功能的哪些位置?

Ark*_*zyk 44

  1. 像这样的东西:

    #!/usr/bin/env bash
    
    set -e
    echo hi
    
    # disable exitting on error temporarily
    set +e
    aoeuidhtn
    echo next line
    
    # bring it back
    set -e
    ao
    
    echo next line
    
    Run Code Online (Sandbox Code Playgroud)

    跑:

    $ ./test.sh
    hi
    ./test.sh: line 7: aoeuidhtn: command not found
    next line
    ./test.sh: line 11: ao: command not found
    
    Run Code Online (Sandbox Code Playgroud)
  2. 它在set内置帮助中描述:

    $ type set
    set is a shell builtin
    $ help set
    (...)
    Using + rather than - causes these flags to be turned off.
    
    Run Code Online (Sandbox Code Playgroud)

此处记录了相同的内容:https : //www.gnu.org/software/bash/manual/bashref.html#The-Set-Builtin


ern*_*nie 29

取消错误保释的另一种方法是无论如何都要强制成功。你可以这样做:

cmd_to_run || true
Run Code Online (Sandbox Code Playgroud)

这将返回 0 (true),因此不应触发 set -e

  • `faulty_cmd || :` 是另一个流行的成语。(`:` 是一个与 `true` 同义的命令)。 (3认同)
  • @ulidtko - 有趣。带我进入兔子洞找到这个 http://stackoverflow.com/questions/3224878/what-is-the-purpose-of-the-colon-gnu-bash-builtin 以获取真实与历史记录: (3认同)

h0t*_*1r3 20

如果您试图捕获返回/错误代码(函数或 fork),这有效:

function xyz {
    return 2
}

xyz && RC=$? || RC=$?
Run Code Online (Sandbox Code Playgroud)

  • 噢,这个人很聪明。找不到使用“set -e”并仍然获取 rc 的方法。我最接近的是将 cmd 放入 if 语句中......我想这就是。不过短得多!谢谢! (2认同)

Gus*_*ave 12

“立即退出 shell 选项”是否适用或被忽略取决于执行命令的上下文(请参阅Bash 参考手册中关于 Set Builtin 的部分- 感谢 Akadiusz Drabczyk)。

特别是,如果命令是 if 语句中测试的一部分,则该选项将被忽略。因此,可以使用如下 if 语句在“立即退出上下文”中执行命令并检查其成功或失败:

#!/bin/bash

set -e

# Uncomment next line to see set -e effect:
#blubb

if blubb; then
  echo "Command blubb was succesful."
else 
  echo "Command blubb failed. Exit code: $?"
fi
echo "Script exited normally."
Run Code Online (Sandbox Code Playgroud)

可以省略“then”语句并使用更少的行:

if blubb; then :;
else echo "Command blubb failed. Exit code: $?"; fi
Run Code Online (Sandbox Code Playgroud)


jwd*_*jwd 9

另一种方法,我发现相当简单(并且适用于set除 之外的其他选项-e):

使用它$-来恢复设置。

例如:

oldopt=$-
set +e
# now '-e' is definitely disabled.
# do some stuff...

# Restore things back to how they were
set -$oldopt
Run Code Online (Sandbox Code Playgroud)

尽管具体而言-e,其他人提到的选项(|| true或“放入if”内)可能更惯用。