Zen*_*Zen 3 bash cron logs shell-script error-handling
记录 crontab 错误的常用方法如下所示:
1 */8 * * * sh /pseudo_path/test.sh 2>> my_err_log
Run Code Online (Sandbox Code Playgroud)
这是一个简洁的命令,但它不能记录错误发生的时间,并且省略了脚本文件的路径。
于是我写了一个错误记录函数:
PROGNAME=$(readlink -f "$0")
SCRIPT_ERR_LOG_PATH="/pseudo_path/script_err_log"
error_exit()
{
timestamp="$(date +%Y%m%d-%H:%M:%S)"
x_info=$(echo "Error_${PROGNAME}:Line_${1:-"null"}_")
zeta=$x_info$timestamp
echo "$zeta" >> $SCRIPT_ERR_LOG_PATH
exit 1
}
Run Code Online (Sandbox Code Playgroud)
该函数可以记录错误发生的时间以及脚本的绝对路径。但缺点是我必须|| error_exit $LINENO在脚本的每一行添加它才能使其工作。使用 Vim 的批量替换可能会容易得多,但它看起来仍然是一个笨拙的解决方案。
那么,有没有更聪明或更有效的方法来完成同样的任务?
在我看来,您正在创建 Bash 脚本,因此请利用 Bash 的trap内置功能。例如:
#!/bin/bash
# vim: ft=sh:tw=75:fo-=t:fo+=rcq:ai:
function error_trap()
{
local -ir __exit_code__=${1:-$?}
local __timestamp__
# Reset the ERR sigspec to its original disposition.
trap - ERR
__timestamp__=$( date --rfc-3339=seconds --date=now )
# Hint...
#declare -p BASH_LINENO
#declare -p BASH_COMMAND
echo "[${__timestamp__}] (Line: ${BASH_LINENO[0]}) :: ERROR :: ${BASH_COMMAND}" >&2
exit ${__exit_code__}
}
# Register function 'error_trap' as the trap handler for
# the ERR (error) sigspec.
trap "{ error_trap; }" ERR
# Try it out; deliberately crash-and-burn this script.
ls this-does-not-exist
Run Code Online (Sandbox Code Playgroud)
这是我调用此脚本时看到的输出:
ls: cannot access this-does-not-exist: No such file or directory
[2015-07-30 01:36:32-05:00] (Line: 24) :: ERROR :: ls this-does-not-exist
Run Code Online (Sandbox Code Playgroud)