Mehrzeilige Shell-Skript-Kommentare - wie funktioniert das?


92

Kürzlich bin ich auf einen mehrzeiligen Kommentartyp gestoßen, den ich noch nie gesehen habe - hier ist ein Skriptbeispiel:

echo a
#
: aaa 
: ddd 
#
echo b

Dies scheint zu funktionieren, sogar die vimSyntax hebt es hervor. Wie heißt diese Art des Kommentierens und wie finde ich weitere Informationen dazu?


1
Was ist, wenn Sie stattdessen Ihren Code in Funktion einwickeln, um ihn auszukommentieren? CommentedOutBlock() { echo "test"; }
Buksy

Antworten:


135

Das ist kein mehrzeiliger Kommentar. #ist ein einzeiliger Kommentar. :(Doppelpunkt) ist überhaupt kein Kommentar, sondern ein in die Shell integrierter Befehl, der im Grunde genommen eine NOP ist , eine Nulloperation, die nichts anderes tut, als true zurückzugeben true(und daher $?als Nebeneffekt auf 0 setzt). Da es sich jedoch um einen Befehl handelt, kann er Argumente akzeptieren, und da er seine Argumente ignoriert, verhält er sich in den meisten Fällen oberflächlich wie ein Kommentar. Das Hauptproblem bei diesem Trick ist, dass die Argumente immer noch erweitert werden, was zu einer Vielzahl von unbeabsichtigten Konsequenzen führt. Die Argumente sind weiterhin von Syntaxfehlern betroffen, Umleitungen werden weiterhin ausgeführt, sodass : > filesie abgeschnitten werden file, und : $(dangerous command)Ersetzungen werden weiterhin ausgeführt.

Der am wenigsten überraschende und völlig sichere Weg, Kommentare in Shell-Skripte einzufügen, ist mit #. Halten Sie sich auch bei mehrzeiligen Kommentaren daran. Versuchen Sie niemals , (ab) :für Kommentare zu verwenden. Es gibt keinen speziellen mehrzeiligen Kommentarmechanismus in der Shell, der der Schrägstrich-Sternform /* */in Cähnlichen Sprachen entspricht.


Der Vollständigkeit halber, aber nicht, weil es eine empfohlene Praxis ist, möchte ich erwähnen, dass es möglich ist, hier-Dokumente zu verwenden, um mehrzeilige "Kommentare" zu machen:

: <<'end_long_comment'
This is an abuse of the null command ':' and the here-document syntax
to achieve a "multi-line comment".  According to the POSIX spec linked 
above, if any character in the delimiter word ("end_long_comment" in 
this case) above is quoted, the here-document will not be expanded in 
any way.  This is **critical**, as failing to quote the "end_long_comment" 
will result in the problems with unintended expansions described above. 
All of this text in this here-doc goes to the standard input of :, which 
does nothing with it, hence the effect is like a comment.  There is very 
little point to doing this besides throwing people off.  Just use '#'.
end_long_comment

29
+1 sehr wichtig, um die einfachen Anführungszeichen in der <<Zeile zu halten - das schaltet Substitution und Expansion aus.
Glenn Jackman

4
Und als zusätzliche Anmerkung: Wenn Sie Shellskripte mit :Dingen füllen , die Kommentare sein sollten, wird zusätzlicher RAM- / CPU-Verbrauch verursacht. Es ist für einfache Dinge auf Ihrem Desktop nicht wichtig, aber wenn es hunderte oder tausende Male pro Sekunde ausgeführt wird, werden Sie nichts tun, sehr schnell .
Bahamat

3
@bahamat: Wenn du etwas hunderte oder tausende Male pro Sekunde ausführst, hoffe ich, dass du es nicht in Shell schreibst ... = /
7heo.tk

1
Manchmal kann es hilfreich sein, das Dienstprogramm null für mehrere Textzeilen zu verwenden. Wenn Sie den Kommentar mit beginnen, können : <<=cutSie POD in Shell-Skripten schreiben. Weitere Informationen finden Sie in diesem Beispiel . Dies ermöglicht die Verwendung perldoc script.sh. Der in dieser Antwort gezeigte mehrzeilige Kommentar sollte jedoch unbedingt ein Kommentarblock sein (jede Zeile beginnt mit # ).
basic6

Hier ist eine nette Diskussion über Heredocs, die sowohl für Kommentare als auch für andere interessante Anwendungsfälle (einschließlich der Erstellung von Dynaimc-Skripten) verwendet wird: tldp.org/LDP/abs/html/here-docs.html#EX71C
bguiz

28

Es ist keine Art zu kommentieren. Der :eingebaute Befehl macht absolut nichts; Es wird hier zum Kommentieren missbraucht.

$ help :
:: :
    Null command.

    No effect; the command does nothing.

    Exit Status:
    Always succeeds.

25

In frühen Muscheln war der Doppelpunkt die einzige Möglichkeit, Kommentare zu erstellen.

Dies ist jedoch kein echter Kommentar, da die Zeile genauso analysiert wird wie jeder andere Befehl, und dies kann Nebenwirkungen haben. Zum Beispiel:

: ${a:=x} # assigns the value 'x' to the variable, 'a'

: $(command) # executes 'command'

(Manchmal wird der Doppelpunkt nur zum Aufrufen dieser Nebenwirkungen verwendet, aber dann wird er nicht als Kommentar verwendet.)

Es ist manchmal praktisch, einen Abschnitt eines Skripts mit dem Doppelpunkt zu kommentieren:

: '
while [ "$n" -ne "$x" ]
do
  : whatever
done
'

Dies ist eine große Zeitersparnis gegenüber dem Voranstellen jeder Zeile #, insbesondere wenn das Auskommentieren nur vorübergehend ist.


2
Diese Kommentierungsmethode mit einfachen Anführungszeichen funktioniert in keinem Skriptabschnitt, der selbst einfache Anführungszeichen verwendet. Und wenn Sie Anführungszeichen weitestgehend so oft verwenden, wie Sie sollten, bedeutet dies, dass das gesamte Skript mit legitimen einfachen Anführungszeichen bestreut ist. Es ist so viel einfacher, einfach einen anständigen Editor zu verwenden, mit dem Sie zeilenweise Kommentare blockieren können.
JW013

Sie haben vollkommen Recht, dass dies nur funktioniert, wenn der angegebene Abschnitt keine einfachen Anführungszeichen enthält. Ein Skript muss jedoch nicht viele einfache Anführungszeichen enthalten. Beim Durchsuchen einiger meiner Skripte finde ich sie relativ spärlich, und viele könnten durch doppelte Anführungszeichen ersetzt werden.
Chris FA Johnson

Die Wahl eines einfachen oder doppelten Anführungszeichens sollte kaum von etwas beeinflusst werden, das so unbedeutend und irrelevant ist wie die Frage, ob der Text Ihres Skripts selbst eine gültige Zeichenfolge mit einfachen Anführungszeichen ist. Einfache Anführungszeichen werden verwendet, um Erweiterungen zu verhindern, während doppelte Anführungszeichen bestimmte Erweiterungen zulassen und zusätzliches Parsen erfordern. Dies ist das eigentliche Kriterium für die Bestimmung, welche verwendet werden soll.
JW013

Dies ist bei weitem die schickste Art, dies zu tun. Ideal für kleine Dokumentationsblöcke. Ich mag es besser als /* */und ugh, fang nicht damit an <!-- -->!
Alex Gray

1

Wenn sich Ihr Kommentar am Ende des Skripts befindet, können Sie dies folgendermaßen tun:

#!/bin/sh
echo 'hello world'
exec true
we can put whatever we want here
\'\"\$\`!#%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
abcdefghijklmnopqrstuvwxyz{|}~
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.