我正在使用以下选项
set -o pipefail
set -e
在 bash 脚本中停止执行错误。我有大约 100 行脚本正在执行,我不想检查脚本中每一行的返回码。
但是对于一个特定的命令,我想忽略该错误。我怎样才能做到这一点?
解决方案:
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
three
永远不会被打印出来。
另外,我想补充一点,当pipefail
打开时,当管道中的命令之一具有非零退出代码时,shell 认为整个管道具有非零退出代码就足够了(pipefail
关闭它必须是最后一个) .
$ set -o pipefail
$ false | true ; echo $?
1
$ set +o pipefail
$ false | true ; echo $?
0
只需|| true
在要忽略错误的命令后添加即可。
不要停止并保存退出状态
以防万一您希望脚本在特定命令失败时不停止,并且您还想保存失败命令的错误代码:
set -e
EXIT_CODE=0
command || EXIT_CODE=$?
echo $EXIT_CODE
更简洁:
! particular_script
从关于(强调我的)的POSIX规范:set -e
当此选项打开时,如果简单命令由于 Shell 错误的后果中列出的任何原因而失败或返回退出状态值 >0,并且在一段时间、直到或 if 关键字之后不属于复合列表的一部分,并且不是 AND 或 OR 列表的一部分,也不是前面有 !的管道 保留字,则shell应立即退出。
除了“返回 true”,您还可以使用“noop”或 null 实用程序(如POSIX 规范中所述):
并且只是“什么也不做”。你会省下几封信。:)
#!/usr/bin/env bash
set -e
man nonexistentghing || :
echo "It's ok.."
如果您想防止脚本失败并收集返回码:
command () {
return 1 # or 0 for success
}
set -e
command && returncode=$? || returncode=$?
echo $returncode
returncode
无论命令成功还是失败,都会被收集。
从这里没有解决方案对我有用,所以我找到了另一个解决方案:
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
这对 CI 和 CD 很有用。这样会打印错误消息,但整个脚本会继续执行。
感谢上面的简单解决方案:
<particular_script/command> || true
以下构造可用于脚本步骤的附加操作/故障排除和附加流控制选项:
if <particular_script/command>
then
echo "<particular_script/command> is fine!"
else
echo "<particular_script/command> failed!"
#exit 1
fi
exit 1
如果需要,我们可以阻止进一步的行动。
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
在使用 CLI 工具时,我一直在使用下面的代码片段,我想知道是否存在某些资源,但我不关心输出。
if [ -z "$(cat no_exist 2>&1 >/dev/null)" ]; then
echo "none exist actually exist!"
fi
我有点喜欢这个解决方案:
: `particular_script`
执行反引号之间的命令/脚本,并将其输出馈送到命令“:”(相当于“真”)
$ false
$ echo $?
1
$ : `false`
$ echo $?
0
编辑:修正了丑陋的错字
虽然|| true
是首选,但你也可以这样做
var=$(echo $(exit 1)) # it shouldn't fail