1
(stdout)/ 2
(stderr)をread
システムコールに渡しましたが、まだうまくいきます。それから0
(stdin)をwrite
システムコールに渡し、それがうまくいくことがわかりました!
int main(int argc, char** argv){
char buf[1024] = "abcdefghi\n";
write(0, buf, 10);
char readbuf[1024] = {0};
// read(1, readbuf, 10); works too
read(2, readbuf, 10);
write(2, readbuf, 10);
return 0;
}
出力:
abcdefghi
hey stdin <-- I input this
hey stdin
とても混乱しています。これはバグだと思います。
実験:
それからfd 2をリダイレクトしようとしています。
$ ./a.out 2>/dev/null
この読み取りまたは第2の書き込みはすべて「表示」されません。出力は次のとおりです
abcdefgi
もしそうなら、stderrを読み込みに使用できますか?
次に、stdoutとstderrを閉じて、stdinのコピーを2つ作成します。
int main(int argc, char** argv){
char buf[1024] = "abcdefghi\n";
close(1);
close(2);
dup2(0, 1);
dup2(0, 2);
write(0, buf, 10);
char redbuf[1024] = {0};
read(2, redbuf, 10);
write(2, redbuf, 10);
return 0;
}
再び動作します。
出力:
abcdefghi
hey stdin <-- I input this
hey stdin
それでは、stdinを書き込みに使用できますか?
ここに説明が必要です。
質問
私は知りたいです:
なぜstdout / stderrを使って読むことができますか?
なぜstdinを使って書くことができますか?
三流です(標準入力、標準出力、標準エラー)内部一つ小川?
そうでなければ、なぜこのような結果が出るのでしょうか?
ベストアンサー1
唯一のルールは、入力/出力/エラーにfd 0/1/2を使用することです。リダイレクトなしでプログラムを呼び出すと、3つすべてがttyを参照し、ttyは読み取りおよび書き込みアクセスで開きます。つまり、必要に応じて読み書きできます。式ストリームは通常、FILE
Cやstream
C ++などのより高いレベルのI / Oに使用されますが、同じストリームと呼ばれることがあります。
これが、リダイレクトの有無にかかわらず、どちらの例も入力したテキストをエコーする理由です。
一方、リダイレクトされると、シェルは読み取り専用または書き込み専用アクセスでファイルを開きます。あなたの例ではリダイレクトされず、画面に表示されるため、./a.out 2>/dev/null
書き込みは端末に接続されています。0
読み取りは2
書き込みにのみ接続されるため/dev/null
失敗する必要がありますが、プログラムの違いは不明です。書き込みは2
成功しましたが、に書き込みます/dev/null
。誤った読み取りと有効な書き込みは/dev/null
端末に表示されません。