Bash脚本:如何确保脚本在使用";调用的函数中出现任何错误时退出;或;(| |)条件?
下面是一个示例脚本:Bash脚本:如何确保脚本在使用";调用的函数中出现任何错误时退出;或;(| |)条件?,bash,shell,error-handling,exit-code,Bash,Shell,Error Handling,Exit Code,下面是一个示例脚本: #!/bin/bash set -euo pipefail function_test () { echo "Everything still ok." thisdoesnotexist echo "It continues running..." } function_test || { echo "Error occured in function_test."; exit 1; } 我希望这个脚本在“thisdoe
#!/bin/bash
set -euo pipefail
function_test () {
echo "Everything still ok."
thisdoesnotexist
echo "It continues running..."
}
function_test || { echo "Error occured in function_test."; exit 1; }
我希望这个脚本在“thisdoesnotexist”上退出,因为set-e被激活了。应该出现错误消息“函数测试中出错”,或者至少应该退出脚本。相反,脚本会继续运行:
$ ./testscript.sh
Everything still ok.
./testscript.sh: Zeile 6: thisdoesnotexist: Kommando nicht gefunden.
It continues running...
我想这是因为根据set
手册,我在“或”(| |)上下文中使用该函数:
立即退出[…],除非失败的命令是
直到或while循环、if语句的一部分、&&or语句的一部分||
清单,[…]
在脚本中处理此问题的最佳方法是什么?我删除了“| |”并使用了如下错误陷阱:
#!/bin/bash
set -Eeuo pipefail
errorhandler () {
echo "Errorhandler called. Exiting."
exit 1
}
trap "errorhandler" ERR
function_test () {
echo "Everything still ok."
thisdoesnotexist
echo "It continues running..."
}
function_test
哪种方法有效:
$ ./testscript.sh
Everything still ok.
./testscript.sh: Zeile 13: thisdoesnotexist: Kommando nicht gefunden.
Errorhandler called. Exiting.
在这种情况下,似乎不可能输出用户友好的消息(例如,其中包含发生错误的脚本中的步骤)。为此,我至少必须将函数名传递给错误陷阱。我试过了,但没有找到有效的解决办法
你有更好的建议吗?如果你想做一些事情以防出错,并且你知道可能会出错,那么:
function_test () {
echo "Everything still ok."
thisdoesnotexist || {
# handle thisdoesnotexist failure
Echo "thisdoesnotexist failed" >&2
exit 1
}
echo "It continues running..."
if ! thisdoesnotexisteither; then
# Handle fail for thisdoesnotexisteither
Echo "thisdoesnotexisteither failed" >&2
exit 1
fi
}
现在,为了在Bash中测试错误处理,您可以使用以下智能错误处理功能:
#!/usr/bin/env bash
# Generate an error
# @Params
# $1: Numeric error return code
# ${2[@]}: Messages
# @Output
# &1: Generic success message
# &2: Generic or passed error messages
# @Return
# $?: Intended return code
erroring() {
local rc=1
if [ "$#" -gt 0 ]; then
rc="$1"
shift
if printf '%d' "$rc" >/dev/null 2>&1; then
# rc is an integer
if [ "$rc" -gt 0 ]; then
printf $"Intended failure with code: %d\\n" "$rc" >&2
if [ "$#" -gt 0 ]; then
# There are supplied messages to print"
printf $"%d messages:\\n" "$#" >&2
printf '%q\n' "$@" >&2
fi
else
echo $"Intended success"
fi
else
printf $"Invalid non-numeric return code parameter: %q\\n" "$rc" >&2
rc=7
fi
else
erroring "$rc"
fi
return "$rc"
}
函数测试| |{echo”在函数测试中发生错误。“退出1;}
由于函数返回状态的原因,OR从不发生。函数的最后一条echo语句导致返回状态为0,因为它已成功运行
如果在未成功执行的命令上添加非零返回,则会导致OR语句正常运行
function_test () {
echo "Everything still ok."
thisdoesnotexist || return 1;
echo "It continues running..."
}
不太容易消耗,但在某些情况下更可取。导出标志和函数,并在子shell中运行它。处理bash错误值
#!/bin/bash
set -euo pipefail
function_test () {
echo "Everything still ok."
thisdoesnotexist
echo "It continues running..."
}
export -f function_test
export SHELLOPTS
bash -c function_test || { echo "Error occured in function_test."; exit 1; }
最后一个
printf$”无效
-这是printf$”无效
?递归调用出错
有什么意义?如果[“$”-gt 0],不只是;然后rc=$1;否则rc=1;fi
更简单吗?这是出错
函数自行失败的原因,因为它被传递了一个非数字返回码。就像调用出错“错误消息”
而不是调用出错1“错误消息”