ディレクトリには多くの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
両方のコマンドに対して行いました。興味深いことに、出力をパイプすると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 +++
wc
12番目のファイルの出力を書き込もうとするとエラーが発生しますEPIPE
。これがhead
行11を取得した後に終了する理由です。終了時には、上記のhead
strace出力に示されているように、最初にパイプに書き込もうとし(もう読み込まれていない)、破損したパイプエラーを受け取りますwc
。SIGPIPE
wc
head
プロセスが他方のプロセスに接続されていないパイプに書き込もうとすると、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