0

我在使用 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

4

1 回答 1

0

太长了,无法发表评论:-)

更改 shebang 以添加#!/bin/sh -x并验证所有内容都根据您的期望进行了扩展。此外,从终端执行时,您的 .bashrc 文件是有源的,从脚本执行时,它不是;可能是您所处环境中不同的东西。找出答案的一种方法是env从终端和脚本执行并区分输出

  • env > env_terminal
  • env > env_script
  • diff env_terminal env_script

狩猎愉快...

于 2011-06-27T17:11:07.037 回答