Existem muitos arquivos txt em um diretório.
Se eu fizer time wc -l *.txt | head
isso, é preciso
real 0m0.032s
user 0m0.020s
sys 0m0.008s
Se eu fizer time wc -l *.txt | tail
isso, é preciso
real 0m0.156s
user 0m0.076s
sys 0m0.088s
Isso significa que você wc
saberá de antemão que está indo direto para a cabeça e contará apenas os 10 primeiros arquivos e economizará tempo? Em outras palavras, ele está ciente do cano? E isso é algo especial wc
ou se aplica a todos os comandos padrão/integrados?
Responder1
Eu fiz um strace
em ambos os comandos. O interessante é que quando você canaliza a saída, head
existem apenas 123 chamadas de sistema. Por outro lado, quando há pipe to tail, há 245 chamadas de sistema (ou mais quando há mais arquivos *.txt).
Caso: cabeça
Aqui estão as últimas linhas ao canalizar 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 +++
Ao wc
tentar gravar a saída do 12º arquivo, ocorre 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 do strace acima, wc
primeiro tenta escrever naquele canal ( head
de onde não lê mais) e recebe um erro informando que o canal está quebrado.
O sinal SIGPIPE é enviado a um processo quando ele tenta escrever em um pipe sem um processo conectado na outra extremidade. -- deWikipédia
Caso: cauda
Ao canalizar para tail
, não há nada parecido com isso acima. wc termina normalmente depois de gravar toda a saída no tubo onde tail
precisa ser 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
Responder2
Qualquer processo que não bloqueie SIGPIPE
será eliminado se sua saída for para a extremidade de gravação de um canal do qual ninguém está lendo.
Então assim que head
fecha sua entrada (ou seja, termina), wc
morre, o que leva menos tempo do que terminar todo o trabalho.
Responder3
Você pode fazer isso para desaparecer seus arquivos:
time wc -l *.txt > tee | tail
Mas um pouco você adiciona tempo para o comando tee 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