我找到了这篇文章,它解释了如何将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 的正确方法是什么?
感谢您的帮助和建议!
这里的问题是脚本退出后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