Answers:
此代码片段会将服务的输出通过管道传送到logger,同时仍允许您执行服务进程(从而替换了shell进程),从而不会混淆新贵。它还可以确保记录器进程已重新绑定到init,因此它不是您的服务的子项,并且即使需要临时创建fifo,也避免了文件系统中的混乱现象。
script
mkfifo /tmp/myservice-log-fifo
( logger -t myservice </tmp/myservice-log-fifo & )
exec >/tmp/myservice-log-fifo
rm /tmp/myservice-log-fifo
exec myservice 2>/dev/null
end script
运作方式如下:
mkfifo /tmp/myservice-log-fifo
只需制作fifo特殊文件(也称为管道)即可。键入man 7 fifo
更多信息。( logger ... </tmp/myservice-log-fifo & )
从后台开始从fifo读取记录器。括号使记录器进程重新初始化为init,而不是保留当前shell进程的子进程。exec >/tmp/myservice-log-fifo
将当前shell的标准输出重定向到fifo。现在我们有了该fifo的打开文件描述符,实际上我们不再需要文件系统条目了...rm /tmp/myservice-log-fifo
因此我们将其删除。exec myservice 2>/dev/null
只需以通常的方式运行服务即可。Stdout已经进入了fifo,并且在执行新程序时不会改变。UPDATE: set -e
不需要,因为Upstart默认使用此选项运行脚本(请参阅 http://upstart.ubuntu.com/cookbook/#develop-scripts-using-bin-sh)
set -e
?
set -e
导致脚本,如果任何命令无法立即退出。如果没有该行,脚本将无用(可能会很危险)继续运行后续命令。
exec 2>&1
上方添加rm
一行,然后2>/dev/null
从最后一行删除。
对于最新的Ubuntu版本(12.04+),只需使用
console log
守护程序输出(STDOUT和STDERR)将附加到 /var/log/upstart/<service>.log
如果使用console output
stanza,然后将脚本的输出通过管道logger
传输到(syslog(3)系统日志模块的shell命令界面),那么它将起作用。
例如
console output
exec /my/script | logger
将登录到 /var/log/messages
例如
console output
exec /my/script | logger -t my-script
将登录/var/log/messages
并标记每个消息my-script
logger --help
记录器使用选项。
(我在基于Centos 5.x的Amazon Linux AMI上; YMMV)
logger
,而不是您实际希望其管理的进程的PID 。
我没有获得mkfifo
令人满意的工作技巧。它似乎没有捕获到stderr,并且尝试重定向导致Upstart保释,没有错误。
不幸的是,使该logger
过程作为的子进程徘徊也有不利的副作用init
,因此有关谁“拥有”记录器的信息会丢失,并且任何尚未意识到这种mkfifo
可能的人都可能认为这是一个悬而未决的过程,可以将其杀死。
相反,我最终得到了以下解决方案,该解决方案解决了所有这些问题。它导致logger
成为子进程,同时将服务保留为根进程。不幸的是,它需要执行bash
,但是看起来很脏。
script
# ... setup commands here, e.g. environment, cd, ...
exec bash <<EOT
exec 1> >(logger -t myservice) 2>&1
exec myservice
EOT
end script
这使用了一种将stdout和stderr重定向到命令的技巧。由于我们在bash
命令内部执行了服务,因此具有替换外壳和神奇地使bash成为服务的子进程的副作用,如下所示ps aufxw
:
myservice
\_ bash -c exec 1> >(logger -t myservice) 2>&1 && exec myservice
\_ logger -t myservice
由于某种原因,上面的命令必须包装在一个bash -c
。我认为这是因为Upstart仅假装通过Bash运行脚本,而实际上不是。如果有人可以提出一种避免使用额外的bash shell的方法,那将是很棒的。
exec bash -l << EOF
那里没有任何损失。
这很丑,但到目前为止我发现的最好的
exec /路径/到/服务器>> /tmp/upstart.log 2>&1
您也可以将输出重定向到syslog,例如
exec $SERVER 2>&1 | logger -t myservice -p local0.info
但是,管道可能会导致新贵将日志记录进程的PID与守护程序的PID混淆。
expect fork
或expect daemon
节。或者cat
,我想您也可以将pid文件放入日志消息中。