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


Answers:


29
  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

    跑:

    $ ./test.sh
    hi
    ./test.sh: line 7: aoeuidhtn: command not found
    next line
    ./test.sh: line 11: ao: command not found
  2. set内置帮助中对此进行了描述:

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

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


谢谢!我发现了另一种可能性:#!/ bin / bash set -e#取消注释下一行以查看set -e效果:#blubb if blubb; 然后回显“命令blubb成功。” 否则,回显“命令blubb失败。退出代码:$?” fi echo正常脚本退出
Gustave 2015年

22

取消对错误的保释的替代方法是无论如何都强制成功。您可以执行以下操作:

cmd_to_run || true

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


3
faulty_cmd || :是另一个流行的成语。(the :是与同义词的命令true)。
ulidtko

3
@ulidtko-有趣。带我到兔子洞去找到这个stackoverflow.com/questions/3224878/…以获取真实vs.的历史:
ernie

12

如果您试图捕获返回/错误代码(函数或派生),则可以这样做:

function xyz {
    return 2
}

xyz && RC=$? || RC=$?

8

是否应用“立即退出外壳程序选项”或被忽略取决于执行命令的上下文(请参阅“内置内置集 -Bash 参考手册”部分 -感谢Arkadiusz 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."

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

if blubb; then :;
else echo "Command blubb failed. Exit code: $?"; fi

2

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

利用$-还原设置。

例如:

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

# Restore things back to how they were
set -$oldopt

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


0

实际上,我最近有一个类似的问题(尽管我没有发布,但我已经解决了),从我所看到的来看,似乎只是在命令之前使用set + e,而在之后使用set -e最优雅。这是一个示例,获取命令的响应并且不让错误将其丢弃。

#!/bin/sh

args=""
for argcol in $*
do
    args="${args} ${argcol}"
done
fortunevar=""
fortfail=""
{
    set +e
    fortunevar=`fortune $args`
    fortfail=$?
    set -e
} &> /dev/null
if [ $fortfail == 0 ]
then
    echo ${fortunevar}
    say ${fortunevar}
else
    echo misfortune: an illegal option was detected!
    echo misfortune: usage: misfortune [-afilosw] [-m pattern][ [#%] file/directory/all]
fi

这将获取“ fortune”的输出,检查其退出状态,然后回显并说出来。我认为这是您要的东西,或者至少是类似的东西?无论如何,希望这会有所帮助。


需要澄清的是,我相信,您将追求的是将大括号中重定向到/ dev / null的位。它使命令没有输出,并在不退出程序的情况下检查其错误状态。
艾迪生·克伦普

0

如果要临时更改某些内容,我喜欢启动subshel​​l。下面的命令演示了第一个bad_command被忽略,​​第二个中止执行。

bash -c 'set -e ;\
( set +e; bad_command ; echo still here ) ;\
echo even here ; \
bad_command ; \
echo but not here;'
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.