と の両方を同じ出力ファイルdup2
にリダイレクトしようとすると、問題が発生します。stdout
stderr
この説明用のコード サンプルを使用しています: (gcc 4.8.2、Ubuntu 14.04)
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#define USE2FILES
int main()
{
int f1, f2, status;
f1 = open("test.out", O_CREAT | O_WRONLY, 0644);
if (f1 == -1) {
perror("open(): ");
}
status = dup2(f1, STDOUT_FILENO);
if (status == -1) {
perror("dup2(): ");
}
#ifdef USE2FILES
close(f1);
#endif
#ifdef USE2FILES
f2 = open("test.out", O_CREAT | O_WRONLY, 0644);
if (f2 == -1) {
perror("dup2(): ");
}
#else
f2 = f1;
#endif
status = dup2(f2, STDERR_FILENO);
if (status == -1) {
perror("dup2(): ");
}
close(f2);
fprintf(stderr, "test_stderr1\n");
fprintf(stdout, "test_stdout1\n");
fprintf(stderr, "test_stderr2\n");
fprintf(stdout, "test_stdout2\n");
fprintf(stderr, "test_stderr3\n");
fprintf(stdout, "test_stdout3\n");
fflush(stdout);
fflush(stderr);
return 0;
}
USE2FILES マクロは、stdout
と にそれぞれ複製される 2 つのファイル記述子 (同じファイルへの) を使用するか、とのstderr
両方に複製される 1 つのファイル記述子を使用するかを切り替えることになっています。stdout
stderr
リダイレクトに 2 つの異なるファイル記述子を使用するとうまくいくはずだという印象を受けました。ただし、このコードを USE2FILES on で実行すると、次の出力が に出力されtest.out
ます。
test_stdout1
test_stdout2
test_stdout3
次に USE2FILES を無効にすると、次のようになります。
test_stderr1
test_stderr2
test_stderr3
test_stdout1
test_stdout2
test_stdout3
最初のケースでは出力stderr
が通過しないようです。この動作は予期されるものですか (何か不足していますか)?
編集:クリス・ドッドの答えを受け入れた後:それは確かに悪い例です。fprintf
シーケンスを次のように変更します。
fprintf(stderr, "test_stderr+++++++++++++++++++++++++++++++++++++++++++++++++1\n");
fprintf(stdout, "test_stdout----------------------------------------1\n");
fprintf(stderr, "test_stderr++++++++++++++++++++++++++++++++++2\n");
fprintf(stdout, "test_stdout----------------2\n");
fprintf(stderr, "test_stderr++++++++++++++++++++++++++++3\n");
fprintf(stdout, "test_stdout----------------------3\n");
test.out
この出力を取得します:
test_stdout----------------------------------------1
test_stdout----------------2
test_stdout----------------------3
err++++++++++++++++++++++++++++3
かなりはっきりstdout
と表示stderr
され、同じファイルに対する書き込みと競合しています。