2014-08-27 3 views
7

Ich bin neu zu bash Scripting und lernen durch einige Beispiele. Eines der Beispiele, die ich sah unter Verwendung einer if-Anweisung zu testen, ob eine zuvor zugewiesene Ausgabedatei gültig ist, wie folgt aus:Was macht diese if-Anweisung von einem Bash-Skript?

if [ -n "$outputFile" ] && ! 2>/dev/null : >> $outputFile ; then 
    exit 1 
fi 

Ich verstehe, was [ -n "$outputFile" ] tut, aber nicht den Rest des bedingten. Kann jemand erklären, was ! 2>/dev/null : >> $outputFile bedeutet/tut?

Ich habe nach Antworten gegoogelt, aber die meisten gefundenen Links waren Erklärungen zur I/O-Umleitung, die definitiv relevant sind, aber immer noch unklar über die Struktur ! : >>.

+0

Wo haben Sie es gesehen? Und was hat es gesagt? –

+0

Könnte als 'if [[$ outputFile]] && [[! -w $ Ausgabedatei]]; dann Ausgang; fi' –

+0

@glennjackman: '-w' nimmt an, dass die Datei bereits existiert, also ist es nicht genau dasselbe. – FatalError

Antwort

5

Das ist etwas seltsam geschriebener Code!

Der Befehl : ist in bash integriert. Es entspricht true; es macht nichts, erfolgreich.

: >> $outputFile 

Versuche nichts zu tun, und fügt die (leer) Ausgabe $outputFile - die bereits bestätigt wurde, eine nicht leere Zeichenfolge zu sein. Der Umleitungsoperator >> erstellt die Datei, falls sie noch nicht existiert.

E/A-Umleitungen wie 2>/dev/null können überall in einem einfachen Befehl angezeigt werden; Sie müssen nicht am Ende sein. Der stdout des Befehls : (der leer ist) wird an $outputFile angehängt, und jede stderr-Ausgabe wird an/dev/null umgeleitet. Jede solche stderr-Ausgabe wäre das Ergebnis eines Fehlers in der Umleitung, da der :-Befehl selbst nichts unternimmt und es nicht versäumt, dies zu tun. Ich weiß nicht, warum die Umleitung von stdout (auf das Ende der $outputFile und die Umleitung von stderr (auf /dev/null) auf gegenüberliegenden Seiten des : Befehls ist

Der ! Operator ist ein logischer „nicht.“; Es überprüft ., ob der folgende Befehl erfolgreich war, und invertiert das Ergebnis

das Nettoergebnis, in Englisch-ish Text geschrieben ist:

wenn „$ output“ gesetzt und ist nicht ein leerer String, und wenn wir keine Berechtigung zum Schreiben haben und dann das Skript mit dem Status 1 beenden.

Kurz gesagt, es testet, ob wir in der Lage sind, $outputFile zu schreiben, und sperrt, wenn wir es nicht tun.

+1

Eins für die gründliche Erklärung! Warum "die Umleitung von stderr (zu/dev/null) auf gegenüberliegenden Seiten des Befehls:" ist, habe ich einige Tests durchgeführt. Eine schreibgeschützte Datei/tmp/bob wird erstellt und ich habe sowohl '2>/dev/null: >>/tmp/bob' und': >>/tmp/bob 2>/dev/null' ausgeführt. Ersteres druckt nichts und letzteres druckt 'bash:/tmp/bob: Berechtigung verweigert '. – BigHead

+0

@GongyuWang: Das ist seltsam; nach '2>/dev/null: >>/tmp/bob' bekomme ich' $? '= 0 (und eine leere'/tmp/bob' Datei). Ich bekomme '$?' = 1, wenn ich zuerst '/ tmp/bob' als Verzeichnis oder als Datei erstelle, die ich nicht schreiben kann (was ich jetzt, nachdem ich deinen gesamten Kommentar gelesen habe, weiß, was du getan hast). –

+1

@GongyuWang: Ich kann die Fehlermeldung vermeiden mit ': 2>/dev/null >>/tmp/bob'. Die '2>/dev/null 'muss dem' >>/tmp/bob' vorangehen; Es muss nicht dem ':' Befehl vorangehen. –

4

Das Skript versucht sicherzustellen, $outputFile ist in einer nicht so naheliegenden Weise beschreibbar.

: ist der Null-Befehl in bash, tut es nichts. Die Tatsache, dass stderr zu /dev/null umgeleitet wird, ist einfach, den Fehler verweigerte Fehler zu unterdrücken, sollte einer auftreten.

Wenn die Datei nicht beschreibbar ist, schlägt der Befehl fehl, wodurch die Bedingung wahr wird, da sie mit ! negiert wird und das Skript beendet wird.

+0

Gute und knappe Antwort! Vielen Dank. – BigHead