パイプ出力が開始/終了するのに必要な時間

パイプ出力が開始/終了するのに必要な時間

ディレクトリには多くの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

wcこれは、ヘッドにパイプされていることを事前に知って最初の10ファイルだけを計算して時間を節約するという意味ですか?つまり、パイプについて知っていますか?これに特別なことがありますかwc?それとも、すべての標準/組み込みコマンドに適用されますか?

答え1

私はstrace両方のコマンドに対して行いました。興味深いことに、出力をパイプするとhead123のシステムコールしかありません。一方、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 +++

wc12番目のファイルの出力を書き込もうとするとエラーが発生しますEPIPE。これがhead行11を取得した後に終了する理由です。終了時には、上記のheadstrace出力に示されているように、最初にパイプに書き込もうとし(もう読み込まれていない)、破損したパイプエラーを受け取りますwcSIGPIPEwchead

プロセスが他方のプロセスに接続されていないパイプに書き込もうとすると、SIGPIPE シグナルがプロセスに送信されます。 - からウィキペディア

ケース:テール

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

答え2

非遮断プロセスの出力がSIGPIPE誰も読み取らないパイプの書き込み終了に達すると、プロセスは終了します。

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

答え3

次の手順でファイルを消去できます。

time wc -l *.txt > tee   | tail 

しかし、teeコマンドに少し時間を追加しました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

関連情報