我使用以下选项

set -o pipefail
set -e

在bash脚本中停止执行错误。我有~100行脚本正在执行,我不想检查脚本中每一行的返回代码。

但是对于一个特定的命令,我想忽略这个错误。我该怎么做呢?


当前回答

更简洁:

! particular_script

关于set -e的POSIX规范(我强调一下):

当该选项打开时,如果一个简单命令由于Shell错误的后果中列出的任何原因而失败,或者返回一个退出状态值>0,并且不在while、until或if关键字后面的复合列表中,不在and或or列表中,并且不是前面有!保留字,则shell应立即退出。

其他回答

解决方案:

particular_script || true

例子:

$ cat /tmp/1.sh
particular_script()
{
    false
}

set -e

echo one
particular_script || true
echo two
particular_script
echo three

$ bash /tmp/1.sh
one
two

第三部永远不会印刷。

另外,我想补充一点,当pipefail打开时, shell认为整个管道具有非零退出代码就足够了 当管道中的某个命令具有非零退出码(pipefail关闭时,它必须是最后一个)。

$ set -o pipefail
$ false | true ; echo $?
1
$ set +o pipefail
$ false | true ; echo $?
0

如果你想防止你的脚本失败并收集返回代码:

command () {
    return 1  # or 0 for success
}

set -e

command && returncode=$? || returncode=$?
echo $returncode

无论命令成功还是失败,都会收集Returncode。

我有点喜欢这个解决方案:

: `particular_script`

在反勾号之间执行命令/脚本,并将其输出提供给命令":"(相当于"true")。

$ false
$ echo $?
1
$ : `false`
$ echo $?
0

编辑:修正了丑陋的错别字

output=$(*command* 2>&1) && exit_status=$? || exit_status=$?
echo $output
echo $exit_status

使用此命令创建日志文件的示例

log_event(){
timestamp=$(date '+%D %T') #mm/dd/yy HH:MM:SS
echo -e "($timestamp) $event" >> "$log_file"
}

output=$(*command* 2>&1) && exit_status=$? || exit_status=$?

if [ "$exit_status" = 0 ]
    then
        event="$output"
        log_event
    else
        event="ERROR $output"
        log_event
fi

只需在希望忽略错误的命令后添加|| true。