Tempo necessário para fazer a saída do pipe para head / tail [duplicate]

4

Existem muitos arquivos txt em um diretório.

Se eu time wc -l *.txt | head é necessário

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

Se eu time wc -l *.txt | tail é necessário

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

Isso significa que wc saberá de antemão que está encabeçando a cabeça e contará apenas os 10 primeiros arquivos e economizará tempo? Em outras palavras, está ciente do tubo? E isso é algo especial sobre wc ou se aplica a todos os comandos padrão / internos?

    
por user13107 08.10.2014 / 03:59

3 respostas

2

Eu fiz um strace em ambos os comandos. O interessante é que quando você canaliza a saída para head , há apenas 123 chamadas de sistema. Por outro lado, quando o pipe para a cauda, existem 245 chamadas de sistema (ou mais, quando há mais arquivos * .txt).

Caso: cabeça

Aqui estão as últimas linhas ao enviar para 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 +++

Quando wc tenta gravar a saída do 12º arquivo, recebe um erro EPIPE . É por isso que head saiu depois de obter a 11ª linha. Quando head sai, wc obtém SIGPIPE . Como visto na saída de strace acima, wc primeiro tenta gravar nesse pipe (onde head não lê mais) e recebe um erro de que o pipe está quebrado.

The SIGPIPE signal is sent to a process when it attempts to write to a pipe without a process connected to the other end. -- from Wikipedia

Caso: final

Ao enviar para tail , não há nada parecido acima. wc termina graciosamente depois de escrever toda a saída para o pipe onde tail precisa estar conectado o tempo todo. tail precisa de todas as linhas antes de poder imprimir as últimas 10 delas. Quando não há mais saída para ler, tail imprime as linhas e sai normalmente também

    
por 08.10.2014 / 09:08
2

Qualquer processo que não bloqueie SIGPIPE será eliminado se sua saída for para o final de gravação de um canal do qual ninguém está lendo.

Então, assim que head fechar sua entrada (ou seja, terminar), wc morrerá, o que levará menos tempo do que terminar todo o trabalho.

    
por 08.10.2014 / 06:20
0

Você pode fazer isso para desaparecer seus arquivos:

time wc -l *.txt > tee   | tail 

Mas um pouco você adiciona tempo para o comando tee em time .

com tee command :

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

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

Sem 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
    
por 08.10.2014 / 04:16