Frage Wie überprüft man, ob ein Befehl erfolgreich war?


Gibt es eine Möglichkeit zu überprüfen, ob bei der Ausführung eines Befehls ein Fehler aufgetreten ist?

Beispiel:

test1=`sed -i "/:@/c connection.url=jdbc:oracle:thin:@$ip:1521:$dataBase" $search`
valid $test1

function valid () {
  if $test -eq 1; then
    echo "OK"
    else echo "ERROR" 
  fi
}

Ich habe es bereits versucht, aber es scheint, dass es nicht funktioniert. Ich weiß nicht, wie das geht.


159
2018-03-07 11:40


Ursprung


Bevorzugen $ (foo) über Backticks `foo`, weil Sie es verschachteln können, und es ist einfacher, von Apostrophen zu unterscheiden. - user unknown
BTW, müssen Sie eine Funktion definieren (valid) bevor du es nennst. - wjandrea


Antworten:


Der Rückgabewert wird in gespeichert $?. 0 zeigt Erfolg an, andere zeigen Fehler an.

some_command
if [ $? -eq 0 ]; then
    echo OK
else
    echo FAIL
fi

Wie jeder andere Textwert können Sie ihn in einer Variablen für den zukünftigen Vergleich speichern:

some_command
retval=$?
do_something $retval
if [ $retval -ne 0 ]; then
    echo "Return code was not zero but $retval"
fi

Für mögliche Vergleichsoperatoren, siehe man test.


238
2018-03-07 12:06



Das ist nett ... kann ich den Ausgabefehler halten ?? !! , denn in diesem Fall habe ich 2 Fehler: Befehlsfehler "Text" ex, Datei nicht gefunden und mein Fehler "Text", der in diesem Fall zum Beispiel fehlgeschlagen ist - moata_u
@moata_u: Sie können den Wert in einer Variablen speichern, wie in meiner Antwort gezeigt. - Lekensteyn
@moata_u: Du musst ein ; Vor dem else und fi: `wenn ...; dann ...; sonst ...; fi - Lekensteyn
Das ist ein nutzloser Gebrauch von test. - David Foerster
@Blauhirn [ $? ] (oder gleichwertig, test $?) funktioniert nicht weil $? wird zu einer Zahl (0, 1 usw.) ausgewertet, die nicht null ist. Siehe die Dokumente für test: "Wenn EXPRESSION weggelassen wird, gibt 'test' false zurück. Wenn EXPRESSION ein einzelnes Argument ist, gibt 'test' false zurück, wenn das Argument Null ist und andernfalls wahr." - Lekensteyn


Wenn Sie nur wissen müssen, ob der Befehl erfolgreich war oder fehlgeschlagen ist, sollten Sie nicht testen $?Testen Sie einfach den Befehl direkt. Z.B.:

if some_command; then
    printf 'some_command succeeded\n'
else
    printf 'some_command failed\n'
fi

Und die Zuweisung der Ausgabe an eine Variable ändert nicht den Rückgabewert (na ja, es sei denn, es verhält sich anders, wenn stdout kein Terminal ist).

if output=$(some_command); then
    printf 'some_command succeded, the output was «%s»\n' "$output"
fi

http://mywiki.wooledge.org/BashGuide/TestsAndConditionals erklärt if ausführlicher.


60
2018-03-08 23:54



Was ist, wenn Sie etwas anderes als das Verzweigen tun möchten, indem Sie den Booleschen Wert dafür speichern, ob es in einer .ini-Datei fehlgeschlagen ist oder nicht? Dann macht deine Ausgabevariable das nicht, aber $? tut, also ist es falsch zu sagen, dass das direkte Testen des Befehls strikt besser ist. - Timothy Swan


command && echo OK || echo Failed

19
2017-12-01 21:19



Ob command gibt Fehler auf dem Bildschirm zurück, wie man es versteckt? - Sigur
Ob command schreibt Fehler in stderr, Sie können das Formular verwenden command 2> /dev/null && echo OK || echo Failed. Das 2> /dev/null leitet die Ausgabe von stderr an /dev/null. Einige Dienstprogramme schreiben jedoch Fehler in stdout (obwohl dies eine schlechte Vorgehensweise ist). In diesem Fall können Sie die 2 aus der Umleitung weglassen, aber Sie werden jede Ausgabe des Befehls verlieren. Diese Methode zur Erfolgskontrolle ist gut für einfache ternäre Logik, aber für komplexeres Verhalten ist es am besten zu überprüfen $? für den Befehlserfolg, oder verwenden Sie die if Block Methode in @ Geirha Antwort beschrieben. - Bender the Greatest


$? sollte den Exit-Status des vorherigen Befehls enthalten, der für keinen Fehler null sein sollte.

Also, sowas wie;

cd /nonexistant
if [ $? -ne 0 ]
then
    echo failed
else
    echo success!
fi

In den meisten Fällen ist es einfacher, das Konstrukt && zu verwenden, um Befehle zu verketten, die voneinander abhängen müssen. Damit cd /nonexistant && echo success! würde nicht Echo-Erfolg, da der Befehl vor && bricht. Die logische Folge davon ist ||, wo cd /nonexistant || echo fail  würde Echo fehlgeschlagen, weil CD fehlgeschlagen ist. (Dies wird nützlich, wenn Sie etwas wie || exit verwenden, wodurch das Skript beendet wird, wenn der vorherige Befehl fehlgeschlagen ist.)


12
2018-03-07 12:04



Das ist nett ... kann ich den Ausgabefehler halten ?? !! , denn in diesem Fall habe ich 2 Fehler: Befehlsfehler "Text" ex, Datei nicht gefunden und mein Fehler "Text", der in diesem Fall zum Beispiel fehlgeschlagen ist - moata_u
@moata_u, siehe mywiki.wooledge.org/BashFAQ/002 - geirha


command && echo $? || echo $?

4
2017-08-12 16:01





Zum Fehlerprüfung Ihre Befehle:

execute [INVOKING-FUNCTION] [COMMAND]

execute () {
    error=$($2 2>&1 >/dev/null)

    if [ $? -ne 0 ]; then
        echo "$1: $error"
        exit 1
    fi
}

Inspiriert in Lean Manufacturing:


2
2017-12-29 04:20





Es ist darauf hinzuweisen, dass if...then...fi und &&/|| Art des Ansatzes behandelt den Beendigungsstatus, der von dem Befehl zurückgegeben wird, den wir testen möchten (0 bei Erfolg); Einige Befehle geben jedoch keinen Beendigungsstatus ungleich Null zurück, wenn der Befehl fehlgeschlagen ist oder die Eingabe nicht möglich ist. Dies bedeutet, dass die üblichen if und &&/|| Ansätze werden für diese bestimmten Befehle nicht funktionieren.

Zum Beispiel unter Linux GNU file wird immer noch mit 0 beendet, wenn es eine nicht existierende Datei als Argument erhalten hat und find konnte die angegebene Datei nicht finden.

$ find . -name "not_existing_file"                                          
$ echo $?
0
$ file ./not_existing_file                                                  
./not_existing_file: cannot open `./not_existing_file' (No such file or directory)
$ echo $?
0

In solchen Fällen können wir mit der Situation umgehen, indem wir lesen stderr/stdin Nachrichten, z.B. diejenigen, die vorbeikamen file Befehl oder parse Ausgabe des Befehls wie in find. Zu diesem Zweck case Aussage könnte verwendet werden.

$ file ./doesntexist  | while IFS= read -r output; do                                                                                                                  
> case "$output" in 
> *"No such file or directory"*) printf "%s\n" "This will show up if failed";;
> *) printf "%s\n" "This will show up if succeeded" ;;
> esac
> done
This will show up if failed

$ find . -name "doesn'texist" | if ! read IFS= out; then echo "File not found"; fi                                                                                     
File not found

(Dies ist ein erneuter Beitrag meiner eigenen Antwort auf verwandte Frage bei unix.stackexchange.com )


0
2017-11-13 18:58





Wie in vielen anderen Antworten erwähnt, ein einfacher Test von $? werde so tun

if [ $? -eq 0 ]; then something; fi

Wenn Sie den Befehl testen möchten gescheitert, können Sie eine kürzere Version in verwenden bash (aber vielleicht übertrieben) wie folgt:

if (($?)); then something; fi

Dies funktioniert mit dem (( )) arithmetischer Modus, also wenn der Befehl zurückgegeben wird success, d.h. $? = 0 dann wird der Test ausgewertet ((0)) was testet als falsesonst wird es zurückkehren true.

Um zu prüfen Erfolg, Du könntest benutzen:

if ! (($?)); then something; fi

aber es ist schon nicht viel kürzer als das erste Beispiel.


0
2017-08-16 21:07