シェルの「デーモン」機能を使用して 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 です。古いものはそうではありません。4月頃から活動を休止しているようです。Ruby のコードは、その頃にはまったく変更されていませんでした。起動スクリプトも同様です。
このように 3 つの異なるサービスを実行しています。そのうちの 2 つは Ruby デーモン (1 つは Sinatra を使用し、1 つは使用しない) で、もう 1 つはバックグラウンド 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
だから、これはルビー(?)がどう相互作用するかの問題だと私には思えます。