読み取りと書き込みの両方にstderrを使用する方法(およびその理由)


12

よるシリーによってこの答えlessそれは開くことができない場合は標準エラー出力からのナビゲーションコマンドを読み込みます/dev/tty

他のプログラムのstderrストリームに書き込むものを見たことがないので、これは不可解なように見えます。

stderrが読み取りと書き込みの両方に対してオープンであることの目的は何ですか?そして、これが便利な場合、現代のシステムでどのように利用するのですか?(たとえば、stdinの代わりにstderrに何かをパイプする難解な構文はありますか?)

回答:


7

最初は驚きました。しかし、答えを読んで、少し調べてみると、簡単に思えます。だからここに私が見つけたものがあります。(最終的には驚きはありませんでした。)

リダイレクト前のstdin、stdout、およびstderrは、予想どおり同じデバイスに接続されています。

#ctrl-alt-delor:~$
#↳ ll /dev/std*
lrwxrwxrwx 1 root root 15 Jun  3 20:58 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 Jun  3 20:58 /dev/stdin -> /proc/self/fd/0
lrwxrwxrwx 1 root root 15 Jun  3 20:58 /dev/stdout -> /proc/self/fd/1

#ctrl-alt-delor:~$
#↳ ll /proc/self/fd/*
lrwx------ 1 richard richard 64 Jun 30 19:14 /proc/self/fd/0 -> /dev/pts/12
lrwx------ 1 richard richard 64 Jun 30 19:14 /proc/self/fd/1 -> /dev/pts/12
lrwx------ 1 richard richard 64 Jun 30 19:14 /proc/self/fd/2 -> /dev/pts/12

したがって、ほとんどのリダイレクト後(つまりstderrの場合)はリダイレクトされません。stderrはまだ端末に接続されています。したがって、キーボード入力を取得するために読み取ることができます。

予期しない方向で使用されているファイルを停止している唯一のものは規則であり、パイプは単方向です。

別の例、試してください:

cat | less

これは、ページlessを読んだ後、端末を読み取ろうとすると失敗します(端末catも読み取っているので、これは驚くことではありません)。

/dev/ttyより神秘的で、へのリンクではありません/proc/self

#ctrl-alt-delor:~$
#↳ ll /dev/tty
crw-rw-rw- 1 root tty 5, 0 Jun 29 09:18 /dev/tty

参照してください。私の現在の制御端末と`は/ dev / tty`の間にある何の関係?説明のために。リンクを提供してくれた@StephenKittに感謝します。


については/dev/ttyこの質問を参照してください。
Stephen Kitt

6

ログインすると、stdin、stdout、およびstderrがログイン元の端末に接続されます。正確には、ttyは通常開かれ、stdoutとstderrはdup(2)最初のファイル記述子の2つの操作の結果です。これにより、端末から入力を取得するためにstderrから読み取ることができます。

他の回答で述べたように、プログラムは質問に対してインタラクティブな応答を得るためにstderrから読み取ります

ユーザーはプログラムがどのような状況でstderrから読み取るかを知ることができないため、別のプログラムから意図的にデータをstderrに書き込むことは無意味な試みです。

今日のプログラムは通常、最初に/dev/ttystderr を開いて使用しようとすることに注意してください。

stderrから読み取るだけのプログラムは、通常、1979年以前から変更されておらず、そのようなプログラムには通常、次のような構造が含まれています。

int i 1;

または

i =* 2;

最近のCコンパイラでは受け入れられません。その結果、今日は決して開か/dev/ttyずにstderrからインタラクティブな応答を読み取るプログラムを見つけることはほとんどありません。


だから私が正しく理解しているなら、シェルはリダイレクトされたstderrときにttyに接続しますstdin(パイプまたは他の手段を介して)?または、常にstderrttyに接続しますか?
Draconis

1
ログインすると、stderrがログイン端末に接続されます。
schily

2
i =+ 1完全に有効なCであり、に等しいi = (+1)。確かに、前者は劣勢のCコンテストの素晴らしい候補です。
G.スリーペン2018年

1
OK、それは警告を生成するだけかもしれません。私は1977年にCから何か他のものにコードを変更
シリー

1
以来、私は、それ以上のシェルを認識していているようです、私はない標準入力以外からの読み込み少なくとも1つのシェルを知っています。(-:
JdeBP 2018
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.