web-dev-qa-db-ja.com

Nohupでstdoutをファイルにリダイレクトできない

Cプログラムをバックグラウンドで実行しようとしています。プログラムのstdout-outputsも保存したいと思います。

しかし、次のことを試してみると、Nohupはstderr-outputsをlogfile.txtにリダイレクトするだけです。

Nohup ./GetTempValues 11 4 > logfile.txt 2>&1 &

11と4はプログラムに渡す必要があるパラメーターで、最後の&はプログラムをバックグラウンドで実行するためのものです(GetTempValuesが私のプログラムです)。

1
Michael Gierer

Guidoが上記で指摘しているように、Nohupは、ファイルにリダイレクトしない限り、すでに標準エラーをリダイレクトしています。 Linuxを使用している場合は、Nohupの下で簡単なコマンドを実行し、dup2(2)の直前にあるexecve(2)の呼び出しを確認するとわかりやすくなります。

私はあなたがあなたが見ていると思うものを見ているとは思えません。あなたが言うときに何が起こるか考えてみましょう

Nohup foo 2>&1
  1. シェルはstderrをstdoutにリダイレクトします。
  2. 次に、その状況を継承するNohupを呼び出します(同じファイル記述子を使用するstderrとstdout)。
  3. NohupNohup.out(ファイル記述子3)を開き、ファイル記述子1に複製し、3を閉じます。
  4. Nohup stderrがファイルではないことに気づき、ファイル記述子を1から2に複製します。したがって、ファイル記述子1と2はどちらもNohup.outを参照します。
  5. Nohupコマンドラインで指定された引数(この場合はfoo)を使用してexecを呼び出します。新しいプロセスは、Nohupに設定されたファイル記述子を継承します。

コマンドラインから、あなたが言うように、Nohupがstderr-outputsのみをリダイレクトするケースを作成することはできません。 Nohupは常にstdoutとstderrをファイルに書き込みます。 stdoutは、リダイレクトを介して指定したもの、またはNohup.outに移動します。 stderrは、明示的に別のファイルにリダイレクトしない限り、stdoutに従います。

Nohup2>&1を使用する際の1つの特有の側面は、GNUのバージョンがstderrで無意味なメッセージを生成することですNohup:入力を無視して 'Nohup.outに出力を追加'。 (他にどのユーティリティが標準エラーにメッセージを書き込んで、指示に従ってドキュメントに従って動作する?)通常、そのノイズは端末に書き込まれます。リダイレクトの下では、出力ファイルの最初の行になります。

3
James K. Lowden

GetTempValuesが最初に標準出力を生成することを確認しますか?あなたの構文は「私のために働く」ので:

$ Nohup Perl test.pl >logfile.txt 2>&1 &
[1] 20964
$ cat logfile.txt 
this goes to stderr
this goes to stdout
[1]+  Done                    Nohup Perl test.pl > logfile.txt 2>&1

ここで、test.pl

print STDOUT "this goes to stdout\n";
print STDERR "this goes to stderr\n";

PS:この例のNohupでは、2>&1を使用してSTDERRをSTDOUTにリダイレクトする必要はありません。これは、 "標準エラーが端末の場合、標準出力と同じ場所に送信されるためです。 。 "Nohupのマニュアルページ)。

6
Guido