Solo estaba ejecutando algunos comandos en una terminal y comencé a preguntarme, ¿Unix / Linux toma atajos cuando ejecuta comandos canalizados?
Por ejemplo, supongamos que tengo un archivo con un millón de líneas, de las cuales las primeras 10 contienen hello world. Si ejecuta el comando, grep "hello world" file | head¿se detiene el primer comando tan pronto como encuentra 10 líneas, o continúa buscando primero todo el archivo?
command-line
pipe
utilities
efficiency
Cabra descontento
fuente
fuente

-margumento.Respuestas:
Más o menos. El shell no tiene idea de lo que harán los comandos que está ejecutando, solo conecta la salida de uno con la entrada del otro.
Si
grepencuentra más de 10 líneas que dicen "hola mundo",headtendrá las 10 líneas que desee y cierre la tubería. Esto provocará lagrepmuerte con un SIGPIPE, por lo que no es necesario que continúe escaneando un archivo muy grande.fuente
grepque seguiría enviando la salida a un vacío, similar a/dev/nullCuando un programa intenta escribir en una tubería y no hay una lectura de proceso de esa tubería, el programa escritor recibe una señal SIGPIPE . La acción predeterminada cuando un programa recibe SIGPIPE es terminar el programa. Un programa puede elegir ignorar la señal SIGPIPE, en cuyo caso la escritura devuelve un error (
EPIPE).En su ejemplo, aquí hay una línea de tiempo de lo que sucede:
grepy seheadinician en paralelo.greplee alguna entrada, comienza a procesarla.grepproduce un primer fragmento de salida.headlee ese primer fragmento y lo escribe.greppodría terminar primero), finalmenteheadhabrá impreso el número deseado de líneas. En este punto,headsalidas.grepyhead, esgrepposible que haya acumulado algunos datos y aún no los haya impreso. En el momento en queheadsale,greppuede estar leyendo entradas o haciendo un procesamiento interno, en cuyo caso continuará haciéndolo.grepescribiremos los datos que se procesan. En ese punto, recibirá un SIGPIPE y morirá.Es probable que
grepprocese un poco más de entrada de lo estrictamente necesario, pero generalmente solo unos pocos kilobytes:headnormalmente se lee en fragmentos de unos pocos kilobytes (porque eso es más eficiente que emitir unareadllamada al sistema para cada byte; este comportamiento se llama almacenamiento en búfer), por lo que el resto del último fragmento después de que se descarta la última línea deseada.greppuede haber acumulado algunos datos que están listos para convertirse en un fragmento de salida (almacenamiento en búfer de nuevo). Recibirá SIGPIPE cuando intente vaciar su búfer de salida.En general, el sistema está diseñado con precisión para que las utilidades de filtrado se comporten de manera eficiente de manera natural. Los programas que necesitan continuar cuando su canal de salida se extingue deben dar el paso de ignorar la señal SIGPIPE.
fuente
En cierto modo, la canalización funciona así: primero ejecuta el primer comando y luego el segundo comando en su caso.
Es decir, seamos
A|Bel comando dado. Entonces es incierto siAoBcomienza primero. Pueden comenzar exactamente al mismo tiempo si hay varias CPU. Una tubería puede contener una cantidad de datos indefinida pero finita.Si B intenta leer desde la tubería, pero no hay datos disponibles,
Besperará hasta que lleguen los datos. SiBestaba leyendo desde un disco,Bpodría tener el mismo problema y necesitar esperar hasta que termine la lectura de un disco. Una analogía más cercana sería leer desde un teclado. Allí,Btendría que esperar a que un usuario escriba. Pero en todos estos casos, B ha comenzado una operación de "lectura" y debe esperar hasta que termine. Pero siBes un comando de tal manera que solo necesita una salida parcial, SIGPIPE mataráAdespués de cierto punto dondeBse alcanza el nivel de entrada de s.ASi
Aintenta escribir en la tubería y la tubería está llena,Adebe esperar a que quede espacio libre en la tubería.Apodría tener el mismo problema si estuviera escribiendo en una terminal. Una terminal tiene control de flujo y puede moderar el ritmo de los datos. En cualquier caso, aA, ha comenzado una operación de "escritura" y esperará hasta que finalice la operación de escritura.AyBse comportan como coprocesos, aunque no todos los coprocesos se comunicarán con una tubería. Ninguno de los dos tiene el control total del otro.fuente
headsale), se produce una señal SIGPIPE en el programa y el comportamiento predeterminado es salir.grepno tiene control directo de la tubería (solo está recibiendo datos), y la tubería no tiene control directo degrep(solo está enviando datos) ...Lo que
grep, o cualquier otro programa hace, depende completamente de la lógica interna de ese programa. Si le indica agreptravés de las opciones de la línea de comandos que haga una salida temprana cuando se encuentre , entonces lo hará, de lo contrario, continuará hasta el final del archivo buscando el patrón ...La Terminal también está bastante desconectada del funcionamiento interno de
greplasshellacciones de tuberías ... La Terminal es básicamente una plataforma de lanzamiento y una pantalla de salida ...fuente