Ich habe viele Shell-Skripte gehackt, und manchmal verwirren mich die einfachsten Dinge. Heute bin ich auf ein Skript :
gestoßen, das das (Doppelpunkt-) Bash-Builtin ausgiebig genutzt hat.
Die Dokumentation scheint einfach zu sein:
: (a colon) : [arguments]
Führen Sie nichts weiter aus, als Argumente zu erweitern und Umleitungen durchzuführen. Der Rückgabestatus ist Null.
Bisher habe ich dies jedoch nur bei Demonstrationen der Shell-Expansion gesehen. Der Anwendungsfall in dem Skript, auf das ich gestoßen bin, hat diese Struktur ausgiebig genutzt:
if [ -f ${file} ]; then
grep some_string ${file} >> otherfile || :
grep other_string ${file} >> otherfile || :
fi
Es gab tatsächlich Hunderte von Greps, aber sie sind nur mehr gleich. Außer der oben beschriebenen einfachen Struktur sind keine Eingabe- / Ausgabe-Umleitungen vorhanden. Später im Skript werden keine Rückgabewerte überprüft.
Ich lese dies als ein nutzloses Konstrukt, das sagt "oder nichts tun". Welchem Zweck könnte es dienen, diese Greps mit "oder nichts tun" zu beenden? In welchem Fall würde dieses Konstrukt ein anderes Ergebnis hervorrufen, als einfach das || :
von allen Instanzen wegzulassen?
quelle
:
als Alternative zutrue
. Vielleichterrexit
ist gesetzt und der Autor kümmert sich nicht um den Exit-Status einiger Befehle.Antworten:
Anscheinend werden die
:
s in Ihrem Skript anstelle von verwendettrue
. Wenngrep
in der Datei keine Übereinstimmung gefunden wird, wird ein Exit-Code ungleich Null zurückgegeben. Wie jw013 in einem Kommentar erwähnt,errexit
wird-e
das Skript beendet, wenngrep
eine Übereinstimmung nicht gefunden wird. Klar, das ist nicht das, was der Autor wollte, so (n) er hinzu|| :
den Exit - Status dieses bestimmten Verbindung Befehl immer Null, wie die häufiger (in meiner Erfahrung) zu machen|| true
/|| /bin/true
.quelle
true
, aber die semantische Absicht ist bei viel klarertrue
.:
ist besser geeignet, wenn eine explizite NOP gewünscht wird.:
statt ,true
da:
ist einbash
Einbau-wo , wie intrue
der Regel eine kompilierte Binärdatei mit mehr Aufwand. Normalerweise benutze ich,true
weil der Code besser lesbar ist (ebenfalls bevorzuge ich die Verwendungsource
statt.
).Das
:
Builtin ist auch bei der Shell-Erweiterung "Standardwerte zuweisen" von Nutzen, bei der die Erweiterung häufig nur für den Nebeneffekt verwendet wird und der erweiterte Wert weggeworfen wird:quelle
Ich kann mir zwei Orte vorstellen, die ich
:
in der Vergangenheit benutzt habe.Das ist eine Endlosschleife.
Setzen Sie eine Stub-Funktion ein, um einen korrekten Kontrollfluss auf höchster Ebene zu erzielen.
Eine Verwendung, die ich früher gesehen habe: Statt einer
#!/bin/sh
(oder was auch immer) Linie würde man eine:
Linie sehen. Einige der älteren Real Unix-Kernel oder Real Unix-Shells würden dies als "Ich bin ein Shell-Skript, lass mich laufen" bezeichnen. Wie ich mich erinnere, war dies gerade, als csh als gemeinsame interaktive Shell Einzug hielt.quelle
:
ist sehr seltsam. Ich fand, dass es in der Tat dazu führt, dass das Skript mit ausgeführt wirdsh
. Wo wie beim Starten des Skripts ohne einen Schebang ... versucht es, das Skript mit der gerade ausgeführten Shell auszuführen (wenn Siebash
es also ausführen, versuchen Sie, es so auszuführen, alsbash
ob Sie es hätten,csh
dann versucht es, es so auszuführencsh
).Die
:
integrierte Version war bereits in der Thompson-Shell enthalten - sie wurde 1975 für Unix V6 dokumentiert . In der Thompson-Shell wurde eine Bezeichnung für den Befehl angegeben. Wenn Sie nie versucht haben, eine Zeile anzufangen, die mit "" beginnt , war diese Zeile praktisch ein Kommentar.:
goto
goto
:
Die Bourne-Shell , der Vorfahr der Bourne / POSIX-Shells, wie wir sie kennen, hatte nie einen
goto
mir bekannten:
Befehl , wurde jedoch als No-Op-Befehl beibehalten (dieser war bereits in Unix V7 vorhanden ).quelle
Ich habe eine alte Referenz ausgegraben: "The UNIX Programming Environment" (c) 1984 von Kernighan und Pike.
Seite 147 (Shell Programming) sagt das:
quelle
true
ist jetzt auf vielen Systemen auch eine Shell eingebaut.Ich scheine mich zu erinnern, dass frühe Versionen der Shell keine Kommentarsyntax hatten. Eine Zeile beginnend mit
:
(die wahrscheinlich eine tatsächliche ausführbare Datei gewesen wäre, ähnlich wie/bin/true
) wäre die beste Alternative gewesen.Hier ist eine Manpage für die alte Thompson-Shell (keine Beziehung); Es wird keine Kommentarsyntax erwähnt.
quelle
:
war in der Tat eine Bezeichnung für dengoto
Befehl in einer alten Shell (ich weiß nicht, welche). Ein Label: something
könnte in der Tat als Kommentar verwendet werden, wenn es keine Übereinstimmung gibtgoto
. Die Praxis blieb auch nach demgoto
Verschwinden.":" ist praktisch zum Debuggen.
Wenn die Debug-Funktion normal ausgeführt wird, wird sie nie ausgeführt. Gehen Sie also einfach über den Noop (Variablen und Platzhalter werden jedoch erweitert). Wenn ein ausführlicheres Debugging erforderlich ist, entfernen Sie das noop aus der Variablen, und die Debugfunktion wird mit den erforderlichen Argumenten aufgerufen.
Eine weitere nützliche Funktion ist der Blockkommentar, der in der Shell-Syntax fehlt.
quelle