シェルがこれらのリダイレクトを次のように解釈するのはなぜですか?

シェルがこれらのリダイレクトを次のように解釈するのはなぜですか?

シェルがリダイレクトを解析する方法の奇妙な動作を理解するのに役立つ人はいますか?

$ cat > test.txt
Line 1
Line 2
$ ls -i dummy.txt dummy2.txt
ls: dummy.txt: No such file or directory
ls: dummy2.txt: No such file or directory
$ 
$ cat test.txt > dummy.txt > dummy2.txt
$ cat dummy2.txt
Line 1
Line 2
$ cat dummy.txt
$

興味深い!私は出力cat test.txtにリダイレクトされ、次のシェルは、dummy.txt入力dummy.txtdummy2.txt。しかし、どういうわけかシェルはそれを別の方法で解析します...

test.txtそれでは、入力へdummy2.txtの内容をどのように完全にバイパスできますかdummy.txt


メモ: bashとkshで同じ結果..

答え1

シェルがリダイレクトされないことを知ることが重要です出力しかし、ファイル記述子。 POSIX準拠のオペレーティングシステムのすべてのプロセスには、STDIN、STDOUT、およびSTDERRの3つのI / Oストリームがあります。リダイレクトは、>STDOUTストリームのファイル記述子をリダイレクトします。したがって、この行を解析するときにシェルが表示する内容は次のとおりです。

  1. cat test.txt- いいね、プログラムを実行しcatてパラメータを入力します。test.txt
  2. > dummy.txt- ああ、今プロセスのSTDOUT記述子を取得し、cat"dummy.txt"というファイルに接続します。以前に何もなかったかどうかに関係なく、ファイルを作成してゼロに切り捨てます。
  3. > dummy2.txt- ああ、今プロセスのSTDOUT記述子cat(以前は「dummy.txt」に接続していた)をインポートし、別の新しいファイルに接続します。代わりにリダイレクトしているため、同時に両方を実行することはできません。繰り返すファイル記述子。

そのため、このコマンドは次のようになります。

find / 2>&1 >/dev/null

STDOUTではエラー出力が発生し、一般(STDOUT)出力は発生しませんが、次のようになります。

find / >/dev/null 2>&1

結果はまったく出力されません。最初のケースでは、STDERRをSTDOUTのコピー(dup)に入れ、古いSTDOUTをごみ箱に入れます。 2番目では、まずSTDOUTをゴミ箱に入れてからコピーして(まだ指しています/dev/null)、STDERRもそこに入れます。

答え2

コメントから回答まで(そのうちのいくつかは推測にもかかわらず):

Bashで実行している場合、

cat test.txt > d1 > d2 > d3 > d4 > d5 

これにより、d1〜d4は空になり、test.txtの内容はd5に保存されます。 Bashは、指定された最後のファイルでのみ実際のリダイレクトを実行するようです。

奇妙なことに、zsh(最小バージョン5)はtest.txtの内容もすべての中間ファイルにコピーします。

Bashのマニュアルページにはリダイレクトの順序が重要であることが示されているので、最後に表示された方向がブローカーよりも優先されるようです。しかし、ファイルがそこにあるので、bashは実際のコンテンツがどこに行くかを調べる前にファイルを生成します。

マニュアルページの特定の部分は次のとおりです。

Note that the order of redirections is significant.  For example, the command

              ls > dirlist 2>&1

directs both standard output and standard error to the file dirlist, 
while the command

              ls 2>&1 > dirlist

directs  only the standard output to file dirlist, because the standard 
error was duplicated from the standard output before the standard output
was redirected to dirlist.

これは、現状を具体的に扱っていないが、命令が重要であることを示唆している。したがって、奇妙なこと(標準出力を別の場所に繰り返しリダイレクト)するときに奇妙な動作を見ると、驚くべき結果が生じる可能性があります。

私は誰かがこの推測のクレイジー(またはマイナーな)間違いをすぐに修正することを確信しています :-)

関連情報