Die -eOption bedeutet "Wenn eine Pipeline jemals mit einem Exit-Status ungleich Null ('Fehler') endet, beenden Sie das Skript sofort". Da grepder Exit-Status zurückgegeben wird, 1wenn keine Übereinstimmung gefunden wird, kann -edas Skript beendet werden, auch wenn kein wirklicher "Fehler" aufgetreten ist.
Wenn Sie die -eOption beibehalten möchten , aber auch einen grepBefehl haben möchten, der möglicherweise keine Übereinstimmungen findet, können Sie ihn || :an den grepBefehl anhängen . Dies bedeutet "oder, wenn der grepBefehl einen Exit-Status ungleich Null zurückgibt, run :(was nichts bewirkt)"; Der Nettoeffekt besteht also darin, -eden grepBefehl zu deaktivieren . Damit:
grep PATTERN FILE... || :
Bearbeitet hinzufügen: Der obigen Ansatz verwirft jeden Fehler: Wenn grepRückkehr , 1weil es keine Einträge gefunden, die ignoriert wird , aber auch , wenn grepRückkehr , 2weil es ein Fehler, die ignoriert wird , und wenn grepnicht in dem Weg (so Bash zurückkehrt 127), dass die ignoriert - und so weiter. Daher ist :es wahrscheinlich besser, einen Befehl zu verwenden, der den Ergebniscode überprüft und den Fehler erneut ausgibt, wenn es sich um etwas anderes handelt 1. Zum Beispiel:
grep PATTERN FILE || (( $? == 1 ))
Dies zerstört jedoch den Exit-Status. Wenn ein fehlgeschlagener Befehl ein Bash-Skript mit beendet -e, gibt das Skript normalerweise den Exit-Status des Befehls zurück. Im obigen Beispiel wird das Skript jedoch nur zurückgegeben 1. Wenn (und nur wenn) uns das interessiert, können wir es beheben, indem wir so etwas schreiben:
grep PATTERN FILE || exit_code=$?
if (( exit_code > 1 )) ; then
exit $exit_code
fi
(erste Zeile c / o dsummersls Kommentar).
An dieser Stelle ist es wahrscheinlich am besten, eine Shell-Funktion zu erstellen, um dies für uns zu erledigen:
function grep_no_match_ok () {
local exit_code
grep "$@" || exit_code=$?
return $(( exit_code == 1 ? 0 : exit_code ))
}
(Beachten Sie die Verwendung von returnanstatt von exit; wir lassen -edas Verlassen gegebenenfalls behandeln); Auf diese Weise können wir einfach schreiben:
grep_no_match_ok PATTERN FILE
Da wir diese Funktion höchstwahrscheinlich für alle Vorkommen grepin diesem Skript verwenden möchten , können wir die Funktion tatsächlich nur benennen grep:
function grep () {
local exit_code
command grep "$@" || exit_code=$?
return $(( exit_code == 1 ? 0 : exit_code ))
}
grep PATTERN FILE
(Beachten Sie die Verwendung von command, um die Shell-Funktion in ihrem eigenen Körper zu umgehen: Wir möchten, dass die Funktion das reguläre Programm grepaufruft, anstatt unendlich zu rekursieren).
-eOption für Bash . Was passiert also wirklich in diesem Fall? :(