1

私は、何らかの形式の redhat OS を搭載した Linux ボックスで 16 時間または 20 時間実行できるプログラムを作成しました。nohup で起動するか、出力をファイルにリダイレクトすると問題なく動作しますが、ユーザーが起動してバックグラウンドに送信し、ログアウトすると、単純なステータス メッセージ (番号の報告) を送信しようとすると失敗します。ファイルの結果)。おそらくストリームが有効でなくなったため、例外がスローされます。

なぜ私にはうまくいったのに、彼にはうまくいかなかったのかがわかったので、いくつかのテストを実行し、Python、Bash、および perl と比較して、この動作において ruby​​ が独特であることを発見しました。

このような状況で、Ruby が他のスクリプト言語と異なる動作をする正当な理由はありますか? 残りのように動作するように変更する方法はありますか?

C++ (および C) は、エンド ユーザーがメッセージの出力を見ることができるかどうかを気にしないと確信していますが、それらの言語のテストは書きませんでした。ログアウトしても、バックグラウンドに送信されたジョブが消えないことに驚きました。したがって、過去にこの動作をテストしたことはありません。

4

2 に答える 2

0

バックグラウンドに移行すると、stdout に書き込もうとするすべての言語のプログラムがエラー コードを受け取るはずです。C の場合、無視できる戻り値が得られます。他の言語では、本当に Ruby だけが例外をスローしたとしたら、私は本当に驚きます。結局、これがOSの作り方であり、問​​題はカーネルにあります。私はperlで1つのデーモンを書きました.nohupなしで殺されないようにするには、stdout、stderr、およびstdinのクローズとダブルフォークを実装する必要があったと確信しています。文書化されていない機能に依存してはならず、nohup に依存して実行するか、入出力記述子を適切に閉じる必要があります。または、低レベルの open 呼び出しを使用してログファイルに再度開きます。

他の言語でもスクリプトとの間でリダイレクトすることを常に試みましたか? program1 の場合、パイプの破損は通常エラーです。program2 匿名パイプは一方の端が閉じられており、もう一方はそこからの読み取り/書き込みを要求しています。

于 2011-11-14T17:22:39.303 に答える
0

ログアウトすると、$stderr と $stdout の受信者であるプロセスが強制終了されます。$stderr および $stdout ファイル記述子は、破損したパイプに接続されています。それらに書き込むときは、オペレーティング システムから SIGPIPE を取得する必要があります。

あなたはC++とCが気にしないことについて間違っています。実装言語や、「ユーザー」が出力を「見る」ことができるかどうかとは何の関係もありません。ファイル記述子がまだ有効かどうかについてです。もう一方の端は閉じているので、もうありません。

C または C++ で書かれたデーモンを見てみましょう。fork の後、exec の前に、子プロセスで stderr と stdout を閉じる方法に注意してください。これは、破損したパイプへの書き込みや、オペレーティング システムによる SIGPIPE の送信から自身を保護する方法です。

于 2011-11-14T17:41:03.050 に答える