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
端末に表示されません。
答え2
stdin/stdout/stderrをリダイレクトしない限り、これらのファイル記述子はログインプロセスによって開き、関連する読み書きファイルは最初のファイルtty
として開き(結果的にファイル記述子#0になります)、dup()
2回呼び出されます。 stdout および stderr ファイル記述子を取得します。
で述べたようにユーザーコマンドを読み取ることができますが、標準入力からデータを「少なく」取得する方法は何ですか?過去には(以前に/dev/tty
取り上げたUNIX
)more
確認を要求したときに読んだのと同じプログラムがありました。stderr