GNU/Linux >> Linux の 問題 >  >> Linux

echo または print /dev/stdin /dev/stdout /dev/stderr

0813 、および 21 ストリームです プロセスのファイル記述子 0、1、2 にそれぞれ付加されます。

端末または端末エミュレーターの対話型シェルのプロンプトで、これら 3 つのファイル記述子はすべて、端末または疑似端末デバイス ファイルを開くことによって取得される同じオープン ファイル記述を参照します (31<のようなもの)。 /コード> ) 読み取り+書き込みモード。

そのインタラクティブ シェルから、リダイレクトを使用せずにスクリプトを開始すると、スクリプトはそれらのファイル記述子を継承します。

Linux では、495362 77 へのシンボリックリンクです 、 8196 それぞれ、それらのファイル記述子で開かれている実際のファイルへの特別なシンボリック リンクです。

これらは stdin、stdout、stderr ではなく、stdin、stdout、stderr が移動するファイルを識別する特別なファイルです (これらの特別なファイルを持つ Linux 以外のシステムでは異なることに注意してください)。

stdin から何かを読み取るということは、ファイル記述子 0 から読み取ることを意味します (これは、107 によって参照されるファイル内のどこかを指します)。 ).

しかし 116 では 、シェルは標準入力から読み取っていないため、標準入力で開いているファイルと同じファイルを読み取るために新しいファイル記述子を開きます(したがって、標準入力が現在指している場所ではなく、ファイルの先頭から読み取ります)。

端末デバイスが読み取り+書き込みモードで開かれているという特殊なケースを除き、通常、stdout と stderr は読み取り用に開かれません。これらは、書き込むストリームであることを意図しています .したがって、ファイル記述子 1 からの読み取りは、通常は機能しません。 Linux で 128 を開く または 139 読み取り用 (142 のように) ) が機能し、stdout が移動するファイルから読み取ることができます (また、stdout がパイプの場合、パイプの反対側から読み取ることになり、ソケットの場合は、できないため失敗します 開く ソケット)

ターミナルの対話型シェルのプロンプトでリダイレクトなしで実行されるスクリプトの場合、/dev/stdin、/dev/stdout、および /dev/stderr のすべてがその /dev/pts/x ターミナル デバイス ファイルになります。 /P>

これらの特殊ファイルから読み取ると、端末から送信されたもの (キーボードで入力したもの) が返されます。それらに書き込むと、テキストが端末に送信されます (表示用)。

echo $(</dev/stdin)
echo $(</dev/stderr)

同じになります。 156 を展開するには 、シェルはその /dev/pts/0 を開き、166 を押すまで入力した内容を読み取ります 空行に。次に、展開 (末尾の改行を取り除き、分割 + グロブの対象となるもの) を 178 に渡します。 その後、stdout に出力されます (表示用)。

ただし、

echo $(</dev/stdout)

180で (そして 199 のみ)、 205 内でそれを認識することが重要です 、stdout がリダイレクトされました。今はパイプです。 218の場合 、子シェル プロセスがファイルの内容を読み取っています (ここでは 221 ) をパイプに書き込み、親はもう一方の端から読み取り、展開を構成します。

この場合、その子 bash プロセスが開くと 235 、それは実際にパイプの読み取り側を開いています。そこからは何も生まれません。行き詰まりの状況です。

スクリプトの stdout が指すファイルから読み取りたい場合は、次の方法で回避できます。

 { echo content of file on stdout: "$(</dev/fd/3)"; } 3<&1

これにより、fd 1 が fd 3 に複製されるため、/dev/fd/3 は /dev/stdout と同じファイルを指します。

次のようなスクリプトを使用:

#! /bin/bash -
printf 'content of file on stdin: %s\n' "$(</dev/stdin)"
{ printf 'content of file on stdout: %s\n' "$(</dev/fd/3)"; } 3<&1
printf 'content of file on stderr: %s\n' "$(</dev/stderr)"

次のように実行する場合:

echo bar > err
echo foo | myscript > out 2>> err

249 に表示されます その後:

content of file on stdin: foo
content of file on stdout: content of file on stdin: foo
content of file on stderr: bar

258 から読み取るのとは対照的に 、 266272 、stdin、stdout、および stderr から読み取りたい場合 (これはあまり意味がありません)、次のようにします:

#! /bin/sh -
printf 'what I read from stdin: %s\n' "$(cat)"
{ printf 'what I read from stdout: %s\n' "$(cat <&3)"; } 3<&1
printf 'what I read from stderr: %s\n' "$(cat <&2)"

2 番目のスクリプトを次のように再度開始した場合:

echo bar > err
echo foo | myscript > out 2>> err

283 に表示されます :

what I read from stdin: foo
what I read from stdout:
what I read from stderr:

そして 294 で :

bar
cat: -: Bad file descriptor
cat: -: Bad file descriptor

stdout および stderr の場合、303 ファイル記述子が書き込み用に開かれているため、失敗します 読むのではなく、314 の展開のみ と 321 空です。

次のように呼び出した場合:

echo out > out
echo err > err
echo foo | myscript 1<> out 2<> err

(ここで 330 切り捨てなしで読み取り+書き込みモードで開きます)、341 に表示されます :

what I read from stdin: foo
what I read from stdout:
what I read from stderr: err

そして 357 で :

err

前の 360379 の内容を上書きしていました 383 で 直後にそのファイル内の標準出力位置を残しました。 393 をプライミングした場合 次のような大きなテキストを使用:

echo 'This is longer than "what I read from stdin": foo' > out

その後、404 に入ります。 :

what I read from stdin: foo
read from stdin": foo
what I read from stdout: read from stdin": foo
what I read from stderr: err

412 の仕組みを見る 最初の 427 の後に残っているものを読みました そしてそうすることで、stdout の位置もそれを超えて移動しました 次の 430 後に読み取られたものを出力します。


449455 出力は、それらから読み取るのではなく、書き込むことしかできません。例:

echo "this is stdout" >/dev/stdout
echo "this is stderr" >/dev/stderr

プログラムはデフォルトで stdout に書き込むので、最初のものは次と同等です

echo "this is stdout"

また、次のような方法で stderr をリダイレクトできます

echo "this is stderr" 1>&2

Linux
  1. / dev/randomを使用してLinuxでランダムパスワードを生成する方法

  2. Linuxは複数の連続したパスセパレーター(/ home //// username /// file)をどのように処理しますか?

  3. / dev / stdin、/ dev / stdout、および/ dev / stderrはどの程度移植可能ですか?

  1. / dev/randomと/dev/ urandomをいつ使用するか?

  2. /dev/dm-Z デバイスから /dev/sdX および /dev/mapper/mpathY デバイスをマップする方法

  3. Linux の /dev/zero および /dev/null ファイルとは

  1. Linux:/ dev / console、/ dev / tty、/ dev / tty0の違いは?

  2. /dev/zero から /dev/null への DD ...実際に何が起こるか

  3. /dev/sda と /dev/sda1 の違い