Daemon動作時のファイル出力と標準出力

プログラムをdaemonで動作させた時のログ出力ができない。
プログラムのカレントにある'test.log'というファイルに書き込むとすると・・・

サンプルコード

def daemon &bl
  exit!(0) if fork
  Process.setsid
  exit!(0) if fork
  Dir::chdir("/")
  File.umask(0)
  STDIN.reopen "/dev/null"
  STDOUT.reopen "/dev/null"
  STDERR.reopen "/dev/null"
  yield if block_given?
end

daemon {
  loop {
    File.open(File.dirname($0) + "/test.log", "w") {|f|
      f.puts "test"
    }
    sleep 1
  }
}

ログは出力されない。

絶対パスにしてみる

相対パスだからダメなんだろうか?
絶対パスに修正してみる

...
    File.open("/var/test.log", "w") {|f|
      f.puts "test"
    }
...
$ tail -f /var/test.log
test
test
test

出力された。

IOのことがよくわかっていない

絶対パスに変える!というまでは、

  • STDOUTをnull以外にして、 $0 の値を調べたり
  • File.dirname, File.expand_path を調べたり

という具合に、
「標準出力の指定が悪いのか?」「カレントディレクトリが悪いのか?」など試行錯誤。
結果的にはファイルパスの指定が悪かったというオチ。


まあ、STDOUTを/dev/null以外にリダイレクトしてあげてもいいみたいだけどね。
その辺も含めて、標準入出力を理解してないんだなと自覚。