ヘッド/テールへのパイプ出力に必要な時間

ヘッド/テールへのパイプ出力に必要な時間

ディレクトリ内には txt ファイルがたくさんあります。

もし私がtime wc -l *.txt | headそうするなら

real    0m0.032s
user    0m0.020s
sys     0m0.008s

もし私がtime wc -l *.txt | tailそうするなら

real    0m0.156s
user    0m0.076s
sys     0m0.088s

これは、wchead にパイプされることを事前に認識し、最初の 10 ファイルのみをカウントして時間を節約することを意味しますか? 言い換えると、パイプを認識しているということですか? これは特別なことですwcか、それともすべての標準/組み込みコマンドに適用されますか?

答え1

両方のコマンドで を実行しましたstrace。興味深いのは、出力を にパイプすると、headシステム コールが 123 個しかないことです。一方、 tail にパイプすると、システム コールが 245 個あります (*.txt ファイルが多い場合はそれ以上になります)。

ケース:ヘッド

パイプするときの最後の数行は次のとおりですhead

open("file12.txt", O_RDONLY)            = 3
fadvise64(3, 0, 0, POSIX_FADV_SEQUENTIAL) = 0
read(3, "", 16384)                      = 0
write(1, "0 file12.txt\n", 13)          = -1 EPIPE (Broken pipe)
--- SIGPIPE (Broken pipe) @ 0 (0) ---
+++ killed by SIGPIPE +++

が 12 番目のファイルの出力を書き込もうとするとwc、エラーが発生しますEPIPE。これがhead、11 行目を取得した後に終了した理由です。head終了すると、wcを取得しますSIGPIPE。上記の strace 出力に見られるように、wc最初にそのパイプ (そこからは読み込まれなくなります) に書き込もうとしますheadが、パイプが壊れているというエラーが発生します。

SIGPIPE シグナルは、プロセスがパイプの反対側に接続されていない状態でパイプに書き込もうとしたときに、プロセスに送信されます。 -- からウィキペディア

ケース:尾

にパイプ接続する場合tail、上記のようなものはありません。wc は、tailその間ずっと接続する必要があるパイプにすべての出力を書き込んだ後、正常に終了しますtail。最後の 10 行を出力する前にすべての行が必要です。読み取る出力がなくなったら、tail行を出力して正常に終了します。

答え2

ブロックしないプロセスは、SIGPIPEその出力が、誰も読み取っていないパイプの書き込み側に行くと、強制終了されます。

headしたがって、入力を閉じるとすぐに(つまり終了すると)、wc終了し、すべての作業を完了するよりも時間がかかりません。

答え3

ファイルを消すには、次の操作を実行できます:

time wc -l *.txt > tee   | tail 

ただし、ティーコマンドに少し時間を追加しますtime

tee command

root@debian:/home/mohsen/test# time wc -l *.txt > tee   | tail 

real    0m0.005s
user    0m0.000s
sys 0m0.000s

それなしtee command

root@debian:/home/mohsen/test# time wc -l *.txt | tail 
   8 f3.txt
   7 fi.txt
   5 mydata.txt
   4 newfile.txt
   4 t1.txt
   4 t2.txt
   5 test.txt
   4 text.txt
   0 t.txt
  49 total

real    0m0.004s
user    0m0.000s
sys 0m0.000s

関連情報