Puede alguien explicar por qué obtener el código de salida 141 de la de abajo?

#!/usr/bin/bash

set -o pipefail

zfs list | grep tank
echo a ${PIPESTATUS[@]}

zfs list | grep -q tank
echo b ${PIPESTATUS[@]}

cat /etc/passwd | grep -q root
echo c ${PIPESTATUS[@]}

Puedo obtener

...
a 0 0
b 141 0
c 0 0

De mi entendimiento código de salida 141 es un fracaso, pero la línea de arriba da cero, por lo que debe ser el éxito, diría yo.

3 Comentarios

  1. 47

    Esto es debido a que grep -q sale inmediatamente con un cero de estado tan pronto como se encuentra una coincidencia. El zfs comando se sigue escribiendo a la tubería, pero no hay ningún lector (porque grep ha salido), por lo que es enviado a un SIGPIPE de la señal desde el kernel y se sale con un estado de 141.

    Otro lugar común donde se puede ver este comportamiento es con head. por ejemplo,

    $ seq 1 10000 | head -1
    1
    
    $ echo ${PIPESTATUS[@]}
    141 0

    En este caso, head leer la primera línea y terminado, que genera un SIGPIPE de la señal y seq terminó con 141.

    Ver «El Infame de la Señal SIGPIPE» Del Linux de la Guía del Programador.

    • Convencionalmente, un estado de salida N mayor que 128 indica que el programa fue terminado por la señal de N – 128. Desde SIGPIPE es señal de 13, 141 – 128 = 13 indica que el programa terminó con un SIGPIPE.
    • Hay una manera de que aún puedo utilizar set -o pipefail y grep -q, como me gustaría mantenerlo, ya que tengo muchos de análisis de SSH.
    • No es una cuestión de convención, es cuestión de cómo conchas de acuerdo con los procesos que salir debido a una señal. Para bash, es de 128 + signal_number, pero otros conchas de utilizar otras fórmulas. Ver este excelente post: unix.stackexchange.com/a/99134/9041
    • Consulte Eficaz SIGPIPE manipulación para los problemas con pipefail en bash y alternativa.
    • Tengo el mismo problema y es muy molesto. Una idea: no utilice -q opción con grep, pero redirigir la salida: 1> /dev/null 2>&1. En teoría, un poco más lento como grep procesará toda la entrada, pero, prácticamente: funciona.
    • Esto sólo hizo mucho sentido para mí, después de años de que en realidad nunca va en busca de la respuesta. Gracias!
    • Para evitar la salida 141 con head -c (conteo de bytes), reemplácelo con cut -b start_byte-end_byte.

  2. 5

    No estoy familiarizado con zfs list, pero supongo que se queja acerca de su salida estándar está cerrado grep -q se cierra inmediatamente cuando se encuentra una coincidencia, a diferencia de grep.

Dejar respuesta

Please enter your comment!
Please enter your name here