$ seq 1 12773 | tee /dev/null >(wc -l > tmp.txt) | head -$((0x`openssl rand -hex 7` % `cat tmp.txt` + 1))|tail -1
--> 8473(任意で1〜12773の間)
$ cat tmp.txt
--> 8473
$ seq 1 12774 | tee /dev/null >(wc -l > tmp.txt) | head -$((0x`openssl rand -hex 7` % `cat tmp.txt` + 1))|tail -1
-->(空)
$ cat tmp.txt
--> 8844(任意で1〜12773の間)
$ seq 1 25011 | tee /dev/null >(wc -l > tmp.txt) | cat | head -$((0x`openssl rand -hex 7` % `cat tmp.txt` + 1))|tail -1
--> 13778(任意で1〜25011の間)
$ cat tmp.txt
--> 13778
$ seq 1 25012 | tee /dev/null >(wc -l > tmp.txt) | cat |head -$((0x`openssl rand -hex 7` % `cat tmp.txt` + 1))|tail -1
-->(空)
$ cat tmp.txt
--> 24939(1〜25012の間で任意に)
$ seq 1 46014 | tee /dev/null >(wc -l > tmp.txt) | cat | cat |head -$((0x`openssl rand -hex 7` % `cat tmp.txt` + 1))|tail -1
--> 34111(任意で1〜46014の間)
$ cat tmp.txt
--> 34111(任意で1〜46014の間)
$ seq 1 46015 | tee /dev/null >(wc -l > tmp.txt) | cat | cat |head -$((0x`openssl rand -hex 7` % `cat tmp.txt` + 1))|tail -1
-->(空)
$ cat tmp.txt
--> 343(任意で1〜46014の間)
cat の後の '|'(wc -l > tmp.txt)' 個数が増えるほど、上記コマンドが処理する行数を増やすことができます。
どうなりますか?
答え1
〜のようにアレックスPすでにコメントで説明していますが、パイプラインのコマンドは並列に実行されます。。あなたはこれが真実ではないと確信しているようです。心を開かない限り、何が起こっているのか理解できないという誤解を忘れてください。
プロセスは並列に実行されるため、ジョブの順序は正確な時間に依存し、ある実行から次の実行に複製されない可能性があります。
最初の例では、次のコマンドが並列に実行されます。
seq 1 12773
tee /dev/null
wc -l > tmp.txt
(プロセス交換もパイプを生成し、コマンドを並列に実行します)head -$((0x`openssl rand -hex 7` % `cat tmp.txt` + 1))
- これには3つの異なるコマンドが含まれ、両方のコマンドがhead
終了openssl
したcat
後に開始されます。tail -1
並列に実行されるため、wc -l > tmp.txt
次の出力に関連するランタイムは予測できません。cat tmp.txt
cat tmp.txt
wc
- リダイレクトを実行する前に実行することができ
tmp.txt
、以前の実行からファイルをインポートするか(存在する場合)、ファイルが存在しないと文句を言うことができます。 - リダイレクトの実行後に実行できますが、
wc
この場合、リダイレクトによってファイルが切り捨てられるため、出力が生成される前にファイルは空です。 - 出力の生成中に実行でき
wc
、出力の先頭のみを選択します。ほとんどのシステムでは、wc
出力が自動的に生成されるため(短いため)、これは発生しません。 wc
出力完了後に実行できます。
実験を通して私はあなたと同じ結果を得ました(ほとんどアイドル状態のカーネル3.16を実行しているLinuxシステムで)。 、の出力をseq 1 12773
取得するには。 、を使って空のファイルを選択してください。それでは、12773と12774の間に違いがあるのはなぜですか?しかし、その下の結果はかなり信頼できますか?cat tmp.txt
wc
seq 1 12774
cat tmp.txt
$ seq 1 12774 | wc -c
65538
しきい値は65536バイトで、値は次のとおりです。パイプバッファ容量。このコマンドは最初に実行して完了するhead …
必要があるため、起動速度が遅くなります。開始すると、パイプの前のコマンドがパイプバッファに書き込まれます。パイプバッファがいっぱいになったら、前のコマンドを停止する必要があります。数値が 12773 に達した場合、パイプバッファーは決して埋められないため、実行が以前に完了し (必要な作業がはるかに少なかった)、出力を作成する時間があった可能性が高くなります。ただし、数値が12774を超えると、パイプバッファがいっぱいになり、出力書き込みが中断され、まだ出力書き込みが完了していません。また、空のファイルとして実行します。openssl
cat
seq
openssl
wc
tee
head …
wc
cat
tee
より多くのパイプを追加すると、各パイプには独自のバッファがあるため、遅延する前により多くのスペースがあります。