Bashをより詳しく理解するために、Bashの機能のいくつかを複製してみました。今リダイレクトとパイプ機能を実装しています。これらの概念をより詳細に理解するには、マニュアル(リダイレクトそして管路)、私はいくつかの特別なケースを試してみた結果、理解しにくい結果を得ました。
bash-3.2$ echo test > file | tr -d t < file | wc > file ; cat file
0 0 0
私はこのコマンドの出力が期待されていましたが、1 1 3
結果はです0 0 0
。私はzshで同じコマンドを試しましたが、出力が期待どおりだったので、私の前提のいくつかはbashに対して間違っているようです。簡単に参照できるように、提供されたコマンドを次のように処理しますcmd1 | cmd2 | cmd
。コマンドの実行時に発生する状況は次のとおりです。
- 標準出力~のガイドライン1にリダイレクトされる標準入力~のガイドライン2。
- 標準出力~のガイドライン2にリダイレクトされる標準入力~のコマンド3。
- ガイドライン1実行されます:
- 文書作成または切り捨てられました。
- 標準出力
echo test
にリダイレクトされる文書。 - これエココマンドが実行され、「test」が次の場所に保存されます。文書。
- ガイドライン2実行されます:
- 標準入力
tr -d t
にリダイレクトされる文書。 - これティーコマンドが実行され、「test」が読み込まれます。文書「es」になり、次に出力されます。コマンド3。
- 標準入力
- コマンド3実行されます:
- 文書切りました。
- 標準出力
wc
にリダイレクトされる文書。 - これトイレコマンドは「es」を入力として実行され、「1 1 3」は次の場所に保存されます。文書。
どうやら私の仮定のいくつかは間違っています。
また、次のような他のコマンドも試しました。
bash-3.2$ echo test > file | tr -d t < file | wc >> file ; cat file
test
1 1 3
bash-3.2$ echo test > file | tr -d t < file | wc > file2 ; cat file ; cat file2
test
1 1 3
これらのテストにより、私は仕事が実行される順序や切り捨てが発生したときに私の仮定が間違っていると信じていました。それが何であれ、説明や追加の助けをいただきありがとうございます。
答え1
パイプのコマンドは同時に実行されるため、同じファイルからの読み書きはプロセスのスケジュール方法によって異なります。
特に、手順4.2では、a)左側がまだ何も書き込んでいない可能性があり、b)書き込み中のリダイレクトによってファイルが切り捨てられた可能性があるtr
ため、読み取りを開始するときにファイルにデータが含まれているという保証はありません。echo
wc > file
echo
ファイルに/からリダイレクトするとパイプが上書きされるため、なぜ最初のパイプを使用するのかわかりません。あなたがそこでやっていることは以下に関連しています
echo test > file & tr -d t < file | wc > file; wait; cat file
一般的に、まだ同じレースがすべて含まれているため、あまり良くはありませんが、少なくとも混乱しているパイプラインオペレータはありません。
Zshは、multios
複数の出力リダイレクトを印刷できる点で異なります。みんなターゲットと読み取り可能な複数の入力リダイレクトみんな源泉。標準シェルのような最後のシェルではありません。