你最喜欢在Bash中处理错误的方法是什么?
我在网上找到的处理错误的最好的例子是William Shotts, Jr在http://www.linuxcommand.org上写的。
他建议在Bash中使用以下函数进行错误处理:
#!/bin/bash
# A slicker error handling routine
# I put a variable in my scripts named PROGNAME which
# holds the name of the program being run. You can get this
# value from the first item on the command line ($0).
# Reference: This was copied from <http://www.linuxcommand.org/wss0150.php>
PROGNAME=$(basename $0)
function error_exit
{
# ----------------------------------------------------------------
# Function for exit due to fatal program error
# Accepts 1 argument:
# string containing descriptive error message
# ----------------------------------------------------------------
echo "${PROGNAME}: ${1:-"Unknown Error"}" 1>&2
exit 1
}
# Example call of the error_exit function. Note the inclusion
# of the LINENO environment variable. It contains the current
# line number.
echo "Example of error with line number and message"
error_exit "$LINENO: An error has occurred."
在Bash脚本中是否有更好的错误处理例程?
有时set -e, trap ERR,set -o,set -o pipefail和set -o errtrace不能正常工作,因为它们试图在shell中添加自动错误检测。这在实践中并不奏效。
在我看来,你应该编写自己的错误检查代码,而不是使用set -e和其他东西。如果您明智地使用set -e,请注意潜在的陷阱。
为了避免在运行代码时出现错误,您可以使用exec 1>/dev/null或exec 2>/dev/null
Linux中的/dev/null是一个空设备文件。这将丢弃写入它的任何内容,并在读取时返回EOF。您可以在命令末尾使用此命令
对于try/catch,您可以使用&&或||来实现类似的行为
Use可以像这样使用&&
{ # try
command &&
# your command
} || {
# catch exception
}
或者你可以用if else:
if [[ Condition ]]; then
# if true
else
# if false
fi
$ ?显示最后一个命令的输出,它返回1或0
使用陷阱!
tempfiles=( )
cleanup() {
rm -f "${tempfiles[@]}"
}
trap cleanup 0
error() {
local parent_lineno="$1"
local message="$2"
local code="${3:-1}"
if [[ -n "$message" ]] ; then
echo "Error on or near line ${parent_lineno}: ${message}; exiting with status ${code}"
else
echo "Error on or near line ${parent_lineno}; exiting with status ${code}"
fi
exit "${code}"
}
trap 'error ${LINENO}' ERR
...然后,每当你创建一个临时文件:
temp_foo="$(mktemp -t foobar.XXXXXX)"
tempfiles+=( "$temp_foo" )
并且$temp_foo将在退出时被删除,并将打印当前行号。(set -e同样会给你错误退出的行为,尽管它有严重的警告,并削弱了代码的可预测性和可移植性)。
您可以让trap为您调用错误(在这种情况下,它使用默认的退出代码1和无消息)或自己调用它并提供显式值;例如:
error ${LINENO} "the foobar failed" 2
将以状态2退出,并给出一个显式消息。
或者使用-s extdebug,并对陷阱的第一行进行一些修改,以全面地捕获所有非零退出代码(mind set -e非错误非零退出代码):
error() {
local last_exit_status="$?"
local parent_lineno="$1"
local message="${2:-(no message ($last_exit_status))}"
local code="${3:-$last_exit_status}"
# ... continue as above
}
trap 'error ${LINENO}' ERR
shopt -s extdebug
这也与set -eu“兼容”。