¿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
ksh93
produce un comportamiento diferente:Lo que desencadena el problema es la canalización interna, sin ella, el bucle sale sea cual sea el shell / OS:
cat
está 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
echo
ignora SIGPIPE. También puede reproducir el problema mediante el uso de enenv echo
lugar deecho
(para forzar el uso delecho
binario real ). (Compare también la salida de{ echo hi; echo $? >&2; } | exit 1
y{ 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
|| exit
para que sepa cómo terminar antes, pero el primeroecho
no coincide con el,grep
por 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