Hay muchos archivos txt en un directorio.
Si lo hago, se time wc -l *.txt | head
necesita
real 0m0.032s
user 0m0.020s
sys 0m0.008s
Si lo hago, se time wc -l *.txt | tail
necesita
real 0m0.156s
user 0m0.076s
sys 0m0.088s
¿Significa esto que wc
sabrá de antemano que está en camino y solo contará los primeros 10 archivos y ahorrará tiempo? En otras palabras, ¿es consciente de la tubería? ¿Y esto es algo especial wc
o se aplica a todos los comandos estándar/integrados?
Respuesta1
Hice un strace
en ambos comandos. Lo interesante es que cuando canalizas la salida head
solo hay 123 llamadas al sistema. Por otro lado, cuando se canaliza hacia la cola, hay 245 llamadas al sistema (o más cuando hay más archivos *.txt).
Caso: cabeza
Aquí están las últimas líneas cuando se conecta a 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 +++
Cuando wc
intenta escribir la salida del archivo número 12, aparece un error EPIPE
. Por eso head
salí después de llegar a la línea 11. Cuando head
sale, wc
obtiene SIGPIPE
. Como se ve en el resultado de strace anterior, wc
primero intenta escribir en esa tubería ( head
de donde ya no lee) y obtiene un error que indica que la tubería está rota.
La señal SIGPIPE se envía a un proceso cuando intenta escribir en una tubería sin un proceso conectado al otro extremo. -- deWikipedia
Caso: cola
Cuando se conecta a tail
, no hay nada de eso arriba. wc termina elegantemente después de escribir toda la salida a la tubería a la que tail
debe conectarse durante todo el tiempo. tail
necesita todas las líneas antes de poder imprimir las últimas 10. Cuando no hay más resultados para leer, tail
imprime las líneas y también sale elegantemente
Respuesta2
Cualquier proceso que no se bloquee SIGPIPE
será eliminado si su salida va al extremo de escritura de una tubería desde la que nadie está leyendo.
Entonces, tan pronto como head
cierra su entrada (es decir, termina), wc
muere, lo que lleva menos tiempo que terminar todo el trabajo.
Respuesta3
Puedes hacerlo para desaparecer tus archivos:
time wc -l *.txt > tee | tail
Pero un poco agregas tiempo para el comando tee time
.
Con tee command
:
root@debian:/home/mohsen/test# time wc -l *.txt > tee | tail
real 0m0.005s
user 0m0.000s
sys 0m0.000s
Sin 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