ディレクトリ内には 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
head にパイプされることを事前に認識し、最初の 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