Время, необходимое для вывода по трубе в начало/конец

Время, необходимое для вывода по трубе в начало/конец

В каталоге много 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

Я сделал a 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выходе wcполучает SIGPIPE. Как видно из вывода strace выше, wcсначала пытается записать в этот канал (откуда headбольше не читает) и получает ошибку, что канал сломан.

Сигнал SIGPIPE отправляется процессу, когда он пытается записать данные в канал без процесса, подключенного к другому концу. -- fromВикипедия

Корпус: хвост

При конвейеризации в 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

Связанный контент