2016-04-05 10 views
0

Ich verstehe, dass die Überprüfung auf Fehler in Linux unter Verwendung von $? erfolgen kann. Die Sache ist, dass der $? Wert zurückgesetzt wird, wenn einer der Befehle erfolgreich ausgeführt wird, selbst wenn der vorherige Befehl fehlgeschlagen ist. Der Code, den ich wie unten zum Testen verwenden:

cd /vobs/test2/test3 
if [ $2 = "R" ]; then 
    mv missing ~/missing2 
echo "Created" 

Unter der Annahme, dass mv missing ~/missing2 die $? gescheitert sollte echo "Created" die $? ausgeführt 1 aber aufgrund des letzten Befehl gleich sein werden 0 gleich sein. Wie führe ich einen Scan für den obigen Code durch, so dass $?=1exit 1 Befehl ausgeführt wird. Ich kann ausführen, wenn sonst für jeden Befehl ausgeführt wird, aber es ist nicht der beste Weg, etwas zu tun, oder? Ich brauche dazu bitte einen Rat.

+1

Beachten Sie, dass es hilfreich wäre, wenn Sie ein funktionierendes Fragment des Shell-Skripts gezeigt hätten. Du hast das 'fi' verpasst, was es schwer macht zu erraten, was du wirklich vorhast - war das' echo' im Körper des 'if' oder außerhalb? Die Einrückung hilft uns auch nicht. Im Allgemeinen sollten Sie '" $ 2 "' in Anführungszeichen einschließen (aber es wäre egal, wenn Sie die Anführungszeichen um '' R '' weglassen würden, obwohl ich sie aus Konsistenzgründen hier behalten würde). Wenn Sie sich Sorgen darüber machen, dass ein Befehl fehlschlägt, können Sie ihn testen: 'falls mv fehlt ~/fehlt; dann echo "Erstellt"; else echo "Erstellung fehlgeschlagen"; fi', etc. Oder Sie können 'set -e' verwenden. –

+2

Best Practices sind im Allgemeinen, um Ihre Fehlerbehandlung in einer Weise zu erstellen, die für das vorliegende Skript geeignet ist. 'die() {(($ #)) && echo" $ * "> & 2; Ausgang 1; } 'ist eine nützliche Utility-Funktion für diesen Zweck, gefolgt von Anwendungen wie' cd/vobs/test2/test3 || sterben. –

+0

... 'set -e' kann verwendet werden, erfordert aber ein wenig Sorgfalt und Vorsicht; Siehe meinen Link in einem Kommentar zu der vorhandenen Antwort. –

Antwort

2

Sie können den ersten fehlgeschlagenen Befehl mit set -e beenden. Dies ist Teil einer inoffiziellen "strict bash mode":

  • set -e

    Um alle Fehler zu verlassen auf.

  • set -o pipefail

    in einer Pipeline auf dem ersten Problem scheitern und nicht nur letzte.

  • set -u

    über den Zugang zu nicht definierten Variablen zum Scheitern verurteilt.

+0

Beiseite: 'pipefail' ist so ziemlich allgemein eine gute Idee; die anderen sind umstrittener, während Perls "strikter Modus" einheitlicher als Best Practice gilt. Für die technischen Probleme, die einem Teil dieser Kontroverse zugrunde liegen, siehe BashFAQ # 105: http://mywiki.wooledge.org/BashFAQ/105 –

+0

... nicht, dass 'pipefail' manchmal auch nicht als ein Fehler fungieren kann; Betrachte das Piping zu 'grep -q', und das Element davor in der Pipeline erhält ein' SIGPIPE' und beendet das Nicht-Nullen nachdem die erste Übereinstimmung gefunden wurde. –

+0

Hallo, Ich habe die Menge -e getestet und es funktioniert .Ich habe ein paar Bedenken über Set -e? Hat es die gleiche Funktion als wenn [$? == 1] Exit 1?Wie für die PipefaiI ich lese den Link, den Sie geschrieben haben. Es sagt, dass wenn die $? Wert ist 1 und es gibt einen übergebenen Befehl, der wie "" ausgeführt wird. wie 1 statt 0? Aber wenn ich es auf meinem Code teste, der 3 oder mehr Befehl hat, gibt es mir 0 beim letzten Echo, wenn der 2. Befehl fehlschlägt. So kann Pipfail nur auf 1 oder den letzten Befehl für $ prüfen? stattdessen der ganze Code? – RandyWong

Verwandte Themen