He canalizado una línea en el script bash y quiero verificar si la canalización tiene datos antes de enviarlos a un programa.
Buscando encontré sobre test -t 0
pero no funciona aquí. Siempre devuelve falso.
Entonces, ¿cómo estar seguro de que la tubería tiene datos?
Ejemplo:
echo "string" | [ -t 0 ] && echo "empty" || echo "fill"
Salida:fill
echo "string" | tail -n+2 | [ -t 0 ] && echo "empty" || echo "fill"
Salida:fill
A diferencia de la forma estándar/canónica de probar si la canalización anterior produjo resultados. la entrada debe conservarse para pasarla al programa. Esto generaliza ¿Cómo canalizar la salida de un proceso a otro pero solo se ejecuta si el primero tiene salida? que se centra en el envío de correo electrónico.
Respuesta aceptada:
No hay forma de echar un vistazo al contenido de una tubería utilizando las utilidades de shell comúnmente disponibles, ni hay una forma de leer un carácter de la tubería y luego volver a colocarlo. La única forma de saber que una canalización tiene datos es leer un byte y luego llevar ese byte a su destino.
Así que haz exactamente eso:lee un byte; si detecta un final de archivo, haga lo que quiera cuando la entrada esté vacía; si lee un byte, bifurque lo que desea hacer cuando la entrada no esté vacía, canalice ese byte y canalice el resto de los datos.
first_byte=$(dd bs=1 count=1 2>/dev/null | od -t o1 -A n | tr -dc 0-9)
if [ -z "$first_byte" ]; then
# stuff to do if the input is empty
else
{
printf "\$first_byte"
cat
} | {
# stuff to do if the input is not empty
}
fi
El ifne
La utilidad de moreutils de Joey Hess ejecuta un comando si su entrada no está vacía. Por lo general, no está instalado de forma predeterminada, pero debería estar disponible o ser fácil de construir en la mayoría de las variantes de Unix. Si la entrada está vacía, ifne
no hace nada y devuelve el estado 0, que no se puede distinguir del comando que se ejecuta correctamente. Si desea hacer algo si la entrada está vacía, debe hacer arreglos para que el comando no devuelva 0, lo que se puede hacer haciendo que el caso de éxito devuelva un estado de error distinguible:
ifne sh -c 'do_stuff_with_input && exit 255'
case $? in
0) echo empty;;
255) echo success;;
*) echo failure;;
esac
test -t 0
no tiene nada que ver con esto; comprueba si la entrada estándar es un terminal. No dice nada en un sentido u otro sobre si alguna entrada está disponible.