Cómo implementar 'set -o pipefail' de manera POSIX - casi listo, se necesita ayuda de expertos
Tengo que implementar la opción BASH "set -o pipefail" de manera POSIX para que funcione en varios tipos de LINUX / UNIX. Para explicar un poco, esta opción permite al usuario verificar la ejecución exitosa de todos los comandos canalizados. Con esta opción habilitada este comando cat app.log | grep 'ERROR' falla si 'cat' falla, de lo contrario se suprime el error 'cat'.
Entonces, encontré una muy buena solución aquí:http://cfaj.ca/shell/cus-faq-2.html
run() {
j=1
while eval "\${pipestatus_$j+:} false"; do
unset pipestatus_$j
j=$(($j+1))
done
j=1 com= k=1 l=
for a; do
if [ "x$a" = 'x|' ]; then
com="$com { $l "'3>&-
echo "pipestatus_'$j'=$?" >&3
} 4>&- |'
j=$(($j+1)) l=
else
l="$l \"\$k\""
fi
k=$(($k+1))
done
com="$com $l"' 3>&- >&4 4>&-
echo "pipestatus_'$j'=$?"'
exec 4>&1
eval "$(exec 3>&1; eval "$com")"
exec 4>&-
j=1
while eval "\${pipestatus_$j+:} false"; do
eval "[ \$pipestatus_$j -eq 0 ]" || return 1
j=$(($j+1))
done
return 0
}
La función run () mencionada anteriormente le permite al usuario invocar los comandos canalizados de tal manera:cmd1 \| cmd2 \| cmd3
Si uno de los comandos falla, lo obtienes en $?
Sin embargo, existe un problema, no admite la agrupación de comandos entre tuberías. Quiero poder invocar algo como esto:
run echo "test" ; grep "test" \| awk '{print}'
Cuando lo hago falla la invocación. No puedo obtener la modificación correcta para admitir la agrupación de comandos. El script es un poco demasiado complejo para mis habilidades de bash ... ¿Podría alguien ayudar?
¡Gracias!
Existe una definición de una función run () que permite al usuario ejecutar los comandos canalizados de tal manera: