Die -e
Option bedeutet "Wenn eine Pipeline jemals mit einem Exit-Status ungleich Null ('Fehler') endet, beenden Sie das Skript sofort". Da grep
der Exit-Status zurückgegeben wird, 1
wenn keine Übereinstimmung gefunden wird, kann -e
das Skript beendet werden, auch wenn kein wirklicher "Fehler" aufgetreten ist.
Wenn Sie die -e
Option beibehalten möchten , aber auch einen grep
Befehl haben möchten, der möglicherweise keine Übereinstimmungen findet, können Sie ihn || :
an den grep
Befehl anhängen . Dies bedeutet "oder, wenn der grep
Befehl einen Exit-Status ungleich Null zurückgibt, run :
(was nichts bewirkt)"; Der Nettoeffekt besteht also darin, -e
den grep
Befehl zu deaktivieren . Damit:
grep PATTERN FILE... || :
Bearbeitet hinzufügen: Der obigen Ansatz verwirft jeden Fehler: Wenn grep
Rückkehr , 1
weil es keine Einträge gefunden, die ignoriert wird , aber auch , wenn grep
Rückkehr , 2
weil es ein Fehler, die ignoriert wird , und wenn grep
nicht 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 return
anstatt von exit
; wir lassen -e
das 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 grep
in 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 grep
aufruft, anstatt unendlich zu rekursieren).
-e
Option für Bash . Was passiert also wirklich in diesem Fall? :(