Ruby后台进程STDOUT为空

Posted

技术标签:

【中文标题】Ruby后台进程STDOUT为空【英文标题】:Ruby background process STDOUT is empty 【发布时间】:2011-06-27 14:55:37 【问题描述】:

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

当我在命令行中完全运行该命令时(无论是否添加了沿行某处添加的单个刻度),我都会得到完全相同的扭曲行为 w.r.t.输出日志。所以,在我看来,这是一个红宝石(?)如何与runuser交互的问题?

【问题讨论】:

您使用的是哪个外壳?你确定 shell 可执行文件在 4 月没有改变(从 /usr/bin/bash 到 /usr/bin/zsh,一个新的默认 shell)? 不,正如我编辑代码块以表明,我们正在使用 bash。我刚刚检查过; zsh 甚至没有安装在机器上。 【参考方案1】:

评论太长了:-)

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

env &gt; env_terminal env &gt; env_script diff env_terminal env_script

狩猎愉快...

【讨论】:

环境几乎相同。我看到的唯一区别并没有解释这个问题:SHLVL=1 at term vs 2 in the script(如预期的那样)。接下来:看看“-x”消息告诉我什么。

以上是关于Ruby后台进程STDOUT为空的主要内容,如果未能解决你的问题,请参考以下文章

脚本控制------------------------(以后台模式运行脚本nohup)

shell 脚本中后台执行命令 &

Linux守护进程

linux 后台进程

linux进程管理(进程的前后台调用)

Linux 进程后台运行