2

の下で実行しているときに、Ruby スクリプトでいくつかの紛らわしい動作が見られnohupます。基本的に私はこれをやっています:

require 'logger'

logger_file = open('/mnt/dbsdata/output.log', File::WRONLY | File::APPEND | File::CREAT)
LOGGER = Logger.new(logger_file)
LOGGER.level = Logger::INFO

  def run_command(cmd,display=true)
    if display
      LOGGER.info "Executing: #{cmd}"
    end
    output = `#{cmd} 2>&1` ; results=$?.success?
    if ! results
        LOGGER.error "FAILED to execute #{cmd}"
        LOGGER.error output
        return false
    end
    return true
  end

begin
  run_command("some_longrunning_command", true)
  run_command("some_other_longrunning_command",true)
  # etc...
end

ここで奇妙なのは、上記のように Logger を使用している場合と、putsSTDOUT (nohup.out) に対して通常どおりに使用している場合の両方で、出力タイミングがかなりずれていることです。ログファイルを追跡して、リアルタイムのログメッセージ (ログメッセージ、コマンドの実行、繰り返し) を確認できると思いますが、コマンドが実行されてからずっと後に、多くの古いメッセージを一度にログに記録するためのメッセージの一括フラッシュが発生しています。すでに実行され、完了しています。

シェルから次のようにスクリプトを実行する場合:

`nohup ruby myscript.rb &`

nohup で実行されていない場合、これは期待どおりに動作します。

誰もがこれを経験し、良い回避策を知っていますか?

4

2 に答える 2

2

はっきりとは言えませんが、IO のsync問題のようです。I/O は通常、速度を上げるためにバッファリングされます。RAM はディスクよりもはるかに高速であるため、コードによってデータが要求されるまで、またはディスクがデータを受信できるようになるまで、読み取りと書き込みは一時的に保存されます。Ruby の IO クラスにはsync=、書き込み時にすぐにバッファをフラッシュするよう Ruby に指示できるメソッドがあります。

これはうまくいくはずです:

logger_file = open('/mnt/dbsdata/output.log', File::WRONLY | File::APPEND | File::CREAT)
logger_file.sync = true
LOGGER = Logger.new(logger_file)
LOGGER.level = Logger::INFO

簡単にするために、次を使用して、出力に必要な正しいモードを作成できます。

    logger_file = File.open('/mnt/dbsdata/output.log', 'a')
于 2013-10-18T19:48:12.003 に答える
0

バッファリングのように聞こえます。stderr にログを記録してみて、それが役立つかどうかを確認してください。

于 2013-10-18T19:44:14.947 に答える