Ich muss die BASH "set -o pipefail" -Option auf POSIX-Art implementieren, damit sie auf verschiedenen LINUX/UNIX-Varianten funktioniert . Um dies ein wenig zu erklären, ermöglicht diese Option dem Benutzer, die erfolgreiche Ausführung aller Piped-Befehle zu überprüfen. Mit dieser Option wurde dieser Befehl cat app.log | aktiviert grep 'ERROR' schlägt fehl, wenn 'cat' fehlschlägt, andernfalls wird der 'cat' Fehler unterdrückt.Wie man "set -o pipefail" auf POSIX-Weise implementiert - fast fertig, Expertenhilfe benötigt
So fand ich eine sehr schöne Lösung hier: 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
}
Die oben genannte Funktion run() ermöglicht es dem Benutzer, die verrohrt Befehle in einer solchen Art und Weise aufzurufen: laufen cmd1 \| cmd2 \| cmd3
Wenn einer der Befehle fehlschlägt Sie bekommen es in $?
Es gibt jedoch ein Problem, das die Gruppierung von Befehlen zwischen Pipes nicht unterstützt. Ich möchte in der Lage sein, so etwas aufzurufen:
run echo "test" ; grep "test" \| awk '{print}'
Wenn ich es tue, schlägt der Aufruf fehl. Ich kann nicht die richtige Änderung erhalten, um die Gruppierung von Befehlen zu unterstützen - das Skript ist ein bisschen zu komplex für meine Bash-Fähigkeiten ... Könnte jemand helfen?
Danke!
Es gibt eine Definition eines run() Funktion, die es dem Benutzer ermöglicht, die verrohrt Befehle in einer solchen Art und Weise auszuführen:
';' gruppiert keine Befehle zwischen Pipes in bash. '(...; ...)' oder '{...; ...; } 'tut. – choroba
'set -o pipefail'. 'set -e' ist anders. Dies ist möglich, aber wahrscheinlich mehr Mühe als es wert ist. Ksh unterstützt auch Pipefail und mksh unterstützt 'PIPESTATUS', mit dem sich Pipefail einfach implementieren lässt. Ich würde ernsthaft in Erwägung ziehen, eine andere Sprache zu verwenden, bevor Sie dies in POSIX sh versuchen. – ormaaj
@choroba - das ist was ich meinte. Du hast recht. Dies funktioniert auch nicht. –