我在使用 shell 的“守护进程”功能运行 Sinatra 脚本的启动脚本中遇到了一个奇怪的问题。问题是当我在命令行运行命令时,我得到输出到 STDOUT。如果我在命令行中完全按照脚本中的方式运行命令 - 减去守护程序部分 - 输出将正确重定向到输出文件。但是,当启动脚本运行它时(见下文),我将内容添加到 STDERR 日志而不是 STDOUT 日志。
脚本的相关行:
#!/bin/sh
# (which is and has been a symlink to /bin/bash
# Source function library.
. /etc/init.d/functions
# Set Some Variables
RUNAS="joeuser"
PID=/var/run/myapp.pid
LOG="/var/log/myapp/app-out.log"
ERR_LOG="/var/log/myapp/app-err.log"
APPLICATION_COMMAND="RAILS_ENV=production ruby /opt/myapp/lib/daemons/my-sinatra-app.rb -p 8002 2>>${ERR_LOG} >>${LOG} &"
# Snip a bunch. This is the applicable line from the "start" case:
daemon --user $RUNAS --pidfile $PID $APPLICATION_COMMAND &> /dev/null
现在,时髦的部分:
- 错误日志通过 STDERR 的重定向正确写入。
- 如果我将 >> 和 2>> 的顺序颠倒过来(我在抓稻草,在这里!),行为不会改变:我仍然得到正确记录 STDERR 并且 STDOUT 为空。
- 如果输出日志不存在,则 STDOUT 重定向会创建该文件。但是,该文件仍然是 0 长度。
- 这曾经奏效。日志目录由 log-rotate 维护。所有最近的“输出”日志都是 0 长度。年纪大的不是。它似乎在四月的某个时候停止工作。ruby 代码在那时附近的任何时候都没有改变。启动脚本也没有。
我们以这种方式运行三种不同的服务。其中两个是 ruby 守护进程(一个使用 sinatra,一个不使用),另一个是后台 java 进程。这发生在两个 ruby 进程上,但没有发生在 java 进程上。也许 Ruby 发生了一些变化?
FTR,我们有 ruby 1.8.5 和 RHEL 5.4。
我做了更多的探索。该daemon
函数做了很多事情,但问题的实质是它使用runuser
. 该命令基本上如下所示:
runuser -s /bin/bash - joeuser -c "ulimit -S -c 0 >/dev/null 2>&1 ; RAILS_ENV=production ruby /opt/myapp/lib/daemons/my-sinatra-app.rb -p 8002 '</dev/null' '>>/var/log/myapp/app-out.log' '2>>/var/log/myapp/app-err.log' '&'"
当我在命令行上完全运行该命令时(无论是否添加了沿行某处添加的单个刻度),我都会在输出日志中得到完全相同的错误行为。所以,在我看来,这是一个红宝石(?)如何与runuser
?