SIGPIPE y fallo de tubería bash

SIGPIPE y fallo de tubería bash

Estoy intentando comprender mejor SIGPIPE en Linux.

Ejecuté este experimento: { ls -al /tmp/ ; echo "$?" 1>&2 ; } | head y me hace eco 141, lo cual entiendo es un código de salida que se le da a los procesos que salen con SIGPIPE Anteriormente, he hecho esto muchas veces sin entender los matices SIGPIPEy normalmente lo ejecuto set -eEuo pipefail, estaba tratando de entender por qué mi el código no fallaba todo el tiempo debido a tuberías rotas... Entonces ejecuté este otro experimento: ( set -o pipefail; { ls -al /tmp/ ; echo "$?" 1>&2 ; } | head; )y obtuve un 0 en el eco esa vez... entonces, cuando pipefailestá habilitado, ¿eso significa que SIGPIPEestá suprimido? ¿O estoy entendiendo mal lo que está pasando aquí?

Respuesta1

lspuede lograr escribir toda su salida antes de headsalir y romper la tubería, incluso si la salida lses más larga de lo que headse imprime. Esto es porque:

  • headpuede leer más de lo que eventualmente imprimirá,
  • y de todos modos hay un amortiguador para la tubería.

SIGPIPE se activa mediante la escritura real en una tubería rota. Si lslogra escribir toda su salida antes de headsalir, entonces no habrá ningún acto de escritura que active SIGPIPE.

O lspuede que no logre escribir toda su salida antes de headsalir. Luego intentará escribir más y obtendrá SIGPIPE.

Al lscorrer headen paralelo, creo que en general hay una condición de carrera. Puede suceder que alguna salida particular de lsactive o no SIGPIPE, de forma aleatoria.

Pruebe con yesen lugar de ls …:

{ yes ; echo "$?" 1>&2 ; } | head

o

( set -o pipefail; { yes ; echo "$?" 1>&2 ; } | head; )

yesgenera una salida que no termina por sí sola, por lo que después de headsalir siempre habrá un acto de escritura que activa SIGPIPE. Cada uno de los comandos anteriores te lo dará 141seguro.

Esto no tiene nada que ver con pipefail.

información relacionada