¿Por qué no sale el comando de abajo? En lugar de salir, el ciclo se ejecuta indefinidamente.
Mientras descubrí este comportamiento usando una configuración más compleja, la forma más simple del comando se reduce a lo siguiente.
No sale:
while /usr/bin/true ; do echo "ok" | cat ; done | exit 1
No hay errores tipográficos arriba. Cada '|' Es una pipa. La 'salida 1' representa otro proceso que se ejecutó y salió.
Espero que la "salida 1" provoque un SIGPIPE en el bucle while (escriba en una tubería sin lector) y que se rompa el bucle. Pero, el ciclo continúa corriendo.
¿Por qué no se detiene el comando?
linux
command-line
bash
shell
bash-scripting
stephen.z
fuente
fuente

Respuestas:
Se debe a una elección en la implementación.
Ejecutar el mismo script en Solaris con
ksh93produce un comportamiento diferente:Lo que desencadena el problema es la canalización interna, sin ella, el bucle sale sea cual sea el shell / OS:
catestá recibiendo una señal SIGPIPE en bash pero el shell está iterando el bucle de todos modos.La documentación de Bash dice:
La documentación de Ksh dice:
POSIX declara:
fuente
echoignora SIGPIPE. También puede reproducir el problema mediante el uso de enenv echolugar deecho(para forzar el uso delechobinario real ). (Compare también la salida de{ echo hi; echo $? >&2; } | exit 1y{ env echo hi; echo $? >&2; } | exit 1.)Este problema me ha molestado durante años. Gracias a jilliagre por empujar en la dirección correcta.
Reiterando un poco la pregunta, en mi caja de Linux, esto se cierra como se esperaba:
Pero si agrego una tubería, no se cierra como se esperaba:
Eso me frustró por años. Al considerar la respuesta escrita por jilliagre, se me ocurrió esta maravillosa solución:
QED ...
Bueno, no del todo. Aquí hay algo un poco más complicado:
Esto no funciona bien. Agregué el
|| exitpara que sepa cómo terminar antes, pero el primeroechono coincide con el,greppor lo que el ciclo se cierra de inmediato. En este caso, realmente no está interesado en el estado de salida degrep. Mi solución es agregar otrocat. Entonces, aquí hay un script inventado llamado "decenas":Esto termina correctamente cuando se ejecuta como
tens | head. Gracias a Dios.fuente