Commenti di script shell multilinea: come funziona?


92

Di recente, mi sono imbattuto in un tipo di commento multilinea che non avevo mai visto prima - ecco un esempio di script:

echo a
#
: aaa 
: ddd 
#
echo b

Questo sembra funzionare, anche la vimsintassi lo evidenzia. Come si chiama questo stile di commento e come posso trovare maggiori informazioni a riguardo?


1
E se invece racchiudessi il codice in funzione per commentarlo? CommentedOutBlock() { echo "test"; }
Buksy,

Risposte:


135

Questo non è un commento su più righe. #è un commento a riga singola. :(due punti) non è affatto un commento, ma piuttosto un comando incorporato della shell che è fondamentalmente un NOP , un'operazione nulla che non fa altro che restituire true, come true(e quindi impostare $?su 0 come effetto collaterale). Tuttavia, poiché è un comando, può accettare argomenti e poiché ignora i suoi argomenti, nella maggior parte dei casi agisce superficialmente come un commento. Il problema principale con questo kludge è che gli argomenti sono ancora espansi, portando a una serie di conseguenze indesiderate. Gli argomenti sono ancora influenzati da errori di sintassi, i reindirizzamenti vengono comunque eseguiti, quindi : > fileverranno troncati filee le : $(dangerous command)sostituzioni verranno comunque eseguite.

Il modo meno sorprendente e completamente sicuro per inserire commenti negli script di shell è con #. Attenersi a questo anche per i commenti su più righe. Non tentare mai di (ab) utilizzare :per i commenti. Non esiste un meccanismo di commento multi-linea dedicato nella shell analogo alla /* */forma a stella in Clinguaggi simili.


Per completezza, ma non perché è una pratica raccomandata, citerò che è possibile usare i documenti qui per fare "commenti" su più righe:

: <<'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 molto importante per mantenere le virgolette singole sulla <<riga - che disattiva la sostituzione e l'espansione.
Glenn Jackman,

4
E come nota aggiuntiva, riempire gli script della shell :per cose che dovrebbero essere commenti causerà un consumo extra di RAM / CPU. Non importa per cose semplici sul tuo desktop, ma se è qualcosa eseguito centinaia o migliaia di volte al secondo non farai nulla, molto velocemente .
bahamat,

3
@bahamat: se esegui qualcosa centinaia o migliaia di volte al secondo, spero che non lo scriverai in shell ... = /
7heo.tk

1
A volte, può essere utile utilizzare l'utilità null per più righe di testo. Iniziando il commento con : <<=cutè possibile scrivere POD negli script di shell, vedere questo esempio per i dettagli . Questo rende possibile l'uso perldoc script.sh. Tuttavia, il commento su più righe mostrato in questa risposta è qualcosa che dovrebbe sicuramente essere un blocco di commenti (ogni riga che inizia con # ).
basic6

Ecco una bella discussione su heredocs, usata sia per i commenti che per altri casi d'uso interessanti (inclusa la generazione di script dynaimc): tldp.org/LDP/abs/html/here-docs.html#EX71C
bguiz

28

Non è uno stile di commento. il :comando integrato non fa assolutamente nulla; viene abusato per i commenti qui.

$ help :
:: :
    Null command.

    No effect; the command does nothing.

    Exit Status:
    Always succeeds.

25

Nelle prime conchiglie, i due punti erano l'unico modo per creare commenti.

Tuttavia, non è un vero commento, perché la riga viene analizzata esattamente come qualsiasi altro comando viene analizzato e ciò può avere effetti collaterali. Per esempio:

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

: $(command) # executes 'command'

(A volte i due punti vengono utilizzati esclusivamente allo scopo di invocare quegli effetti collaterali, ma non vengono utilizzati come commenti.)

A volte è conveniente usare i due punti per commentare una sezione di uno script:

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

Questo è un grande risparmio di tempo rispetto al precedente di ogni riga #, in particolare se il commento è solo temporaneo.


2
Quel metodo di commento con virgolette singole non funziona su nessuna sezione di script che utilizza le virgolette singole. E se stai usando virgolette ovunque vicino a te, ciò significa che avrai tutte le virgolette singole legittime sparse in tutto lo script. È molto più semplice usare qualsiasi editor decente che ti consenta di bloccare i commenti in linea.
jw013,

Hai perfettamente ragione che funzionerà solo se non ci sono virgolette singole nella sezione quotata. Tuttavia, uno script non deve contenere molte virgolette singole. Osservando alcuni dei miei script, li trovo relativamente scarsi e molti potrebbero essere sostituiti da virgolette doppie.
Chris FA Johnson,

La scelta di virgolette singole o virgolette doppie non dovrebbe essere influenzata da qualcosa di così banale e irrilevante per quanto riguarda il fatto che il testo del tuo script sia esso stesso una stringa a virgoletta singola valida. Le virgolette singole vengono utilizzate per impedire le espansioni, mentre le virgolette doppie consentono determinate espansioni e richiedono un'analisi aggiuntiva. Questo è il vero criterio per determinare quale utilizzare.
jw013,

Questo è di gran lunga il modo più chic di farlo. Ottimo per piccoli blocchi di documentazione. Mi piace meglio di /* */e ugh, non farmi iniziare <!-- -->!
alex gray,

1

Se il tuo commento è alla fine dello script, puoi farlo in questo modo:

#!/bin/sh
echo 'hello world'
exec true
we can put whatever we want here
\'\"\$\`!#%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
abcdefghijklmnopqrstuvwxyz{|}~
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.