我找到了这个article,它解释了如何将bash脚本的输出重定向到syslog。这正是我所需要的,但是有一个问题。
#!/bin/bash
# Don't ignore any error and return when first error occurs.
exec 1> >(logger -s -t $(basename $0)) 2>&1
set -e
# a list of command(s) that can fail:
chown -R user1:user1 /tmp/myappData/*
chown -R user1:user1 /tmp/myappTmp/*
chown -R user1:user1 /tmp/myappLog/*
#...
exit 0
当我执行上面的脚本,并且发生错误时,我看到有时,脚本执行后提示不会返回。我无法弄清楚为什么会这样。除非我按回车键,否则提示不会返回。
我担心如果应用程序使用此脚本,则可能无法获得正确的退出代码。
如果我注释掉“set -e”,那么在执行脚本后,提示将始终正确返回。
所以我的问题是,设置脚本的正确方法是什么,以便在出错时退出,并将相应的消息记录到syslog中?
感谢您的帮助和建议!
答案 0 :(得分:2)
此处的问题是,在您的脚本退出后,logger
管道仍在运行,因此在父shell发出提示后,要记录的最后一些内容将打印。如果向上滚动,您会发现隐藏在先前输出中某处的提示。
如果你有一个非常非常的新bash,你可以收集进程替换的PID,并在以后收集wait
。
exec {orig_out}>&1 {orig_err}>&2 1> >(logger -s -t "${0##*/}") 2>&1; logger_pid=$!
[[ $logger_pid ]] || { echo "ERROR: Needs a newer bash" >&2; exit 1; }
cleanup() {
exec >&$orig_out 2>&$orig_err
wait "$logger_pid"
}
trap cleanup EXIT
使用较旧的bash,您可以考虑其他技巧。例如,在Linux上,只要记录器正在运行,就可以使用flock
命令在退出之前尝试获取对锁文件的独占访问权限。
log_lock=$(mktemp "${TMPDIR:-/tmp}/logger.XXXXXX")
exec >(flock -x "$log_lock" logger -s -t "${0##*/}") 2>&1
cleanup() {
exec >/dev/tty 2>&1 || exec >/dev/null 2>&1
flock -x "$log_lock" true
}
trap cleanup EXIT