3

One、Two、Three という名前のディレクトリに 3 つのファイルがあります。

1 つに含まれるもの:

asdfg

2 つの内容:

qwerty

3 つの内容:

zxcvb

次のコマンドを与えると:

$ls > One > Two > Three

次に、次のコマンドを実行します。

$cat One

出力:

Nothing

次に、次のコマンドを実行します。

$cat Two

出力:

Nothing

次に、次のコマンドを実行します。

$cat Three

出力:

One
Three
Two

ここで何が起こっているのか、誰かに光を当てることはできますか? ファイル One と Two が空になり、ls コマンドの出力がファイル Three だけに書き込まれるのはなぜですか?

4

2 に答える 2

3

ここで 述べたようbashに、逆多重化はサポートされておらず、多重化もサポートされていません。表示されている効果は、各ファイルが開かれることですO_TRUNC。つまり、すべてのコンテンツが破棄されます。複数のリダイレクトが指定されている場合、それらはすぐに再び閉じられ、最後のリダイレクトのみが保持され、実際にデータを受け取ります。

straceコマンドの実行の抜粋を次に示します。

strace -f -e open,dup2,close bash -c 'ls > one > two > three'
...
open("one", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
dup2(3, 1)                  = 1
close(3)                    = 0
open("two", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
dup2(3, 1)                  = 1
close(3)                    = 0
open("three", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
dup2(3, 1)                  = 1
close(3)                    = 0
...

ご覧のとおり、bash は同じファイル記述子を上書きし続けます。したがって、最後のものだけがデータを受け取ります。回避策の 1 つは、teewhich を使用して、受け取ったものstdinをすべての引数に書き込むことと、次のようにすることstdoutです。

ls | tee One Two Three > /dev/null 

ちなみに、zshこれをサポートしています:

 zsh$ setopt multios
 zsh$ ls > One > Two > Three
于 2012-09-15T19:14:06.870 に答える
2

リダイレクトできるのは 1 回だけです。最初のリダイレクトは、最初のファイルを書き込み用に開き (以前の内容を削除します)、次のリダイレクトがそれをオーバーライドするとすぐに閉じます。

teeコマンドを探しているようです。

于 2012-09-15T19:09:02.830 に答える