我使用以下选项
set -o pipefail
set -e
在bash脚本中停止执行错误。我有~100行脚本正在执行,我不想检查脚本中每一行的返回代码。
但是对于一个特定的命令,我想忽略这个错误。我该怎么做呢?
我使用以下选项
set -o pipefail
set -e
在bash脚本中停止执行错误。我有~100行脚本正在执行,我不想检查脚本中每一行的返回代码。
但是对于一个特定的命令,我想忽略这个错误。我该怎么做呢?
当前回答
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
其他回答
解决方案:
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
我找到了另一种解决方法:
set +e
find "./csharp/Platform.$REPOSITORY_NAME/obj" -type f -iname "*.cs" -delete
find "./csharp/Platform.$REPOSITORY_NAME.Tests/obj" -type f -iname "*.cs" -delete
set -e
你可以通过set +e来关闭错误失败,这将忽略该行之后的所有错误。一旦完成,并且希望脚本在任何错误时再次失败,可以使用set -e。
应用set +e后,当找不到文件时,find不再使整个脚本失败。同时,错误消息 仍然打印From find,但整个脚本继续执行。因此,如果这导致了问题,则很容易进行调试。
这对CI和CD很有用(例如在GitHub Actions中)。
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。
更简洁:
! particular_script
关于set -e的POSIX规范(我强调一下):
当该选项打开时,如果一个简单命令由于Shell错误的后果中列出的任何原因而失败,或者返回一个退出状态值>0,并且不在while、until或if关键字后面的复合列表中,不在and或or列表中,并且不是前面有!保留字,则shell应立即退出。