Modo per creare commenti multilinea in Bash?


226

Di recente ho iniziato a studiare lo script di shell e mi piacerebbe poter commentare una serie di righe in uno script di shell. Voglio dire, è nel caso di C / Java:

/* comment1
   comment2 
   comment3
*/`

Come potrei farlo?


2
Puoi usare l'hash come: #questo è un commento.
Mohammad Tayyab,

1
Lo so, ma è un po 'problematico per multiline.
Enes Malik Turhan,

2
Va notato che le risposte di seguito richiedono che :sia nella prima colonna (senza spazi iniziali) nella riga.
Ty

Risposte:


394

Utilizzare : 'per aprire e 'chiudere.

Per esempio:

: '
This is a
very neat comment
in bash
'

27
:( e aggiunge anche una grande quantità di capacità di non lettura e potenziale fonte di bug. IMHO è meglio usare solo più #s e mai questo ...
jm666

51
@ jm666 IMHO Mai una buona idea usare la parola mai quando non si ha idea di tutti i casi d'uso.
Inverno

19
per spiegare: :è una scorciatoia per truee truenon elabora alcun parametro. (pagina del manuale:SYNOPSIS true [ignored command line arguments]
phil294,

46
Lo spazio tra :ed 'è importante
becko

23
L'ho modificato leggermente per i blocchi di codice in modo da poter attivare o disattivare facilmente il codice. La mia modifica è quella di utilizzare # 'l'ultima riga anziché la singola citazione. In questo modo posso mettere un singolo #sulla prima riga per attivare il blocco di codice. Rimuovere la #prima riga per disattivare il codice.
JohnMudd,

131

Commento multilinea in bash

: <<'END_COMMENT'
This is a heredoc (<<) redirected to a NOP command (:).
The single quotes around END_COMMENT are important,
because it disables variable resolving and command resolving
within these lines.  Without the single-quotes around END_COMMENT,
the following two $() `` commands would get executed:
$(gibberish command)
`rm -fr mydir`
comment1
comment2 
comment3
END_COMMENT

4
Funziona, la risposta attualmente accettata no (per me).
Freek,

5
Vale probabilmente la pena notare che questo non è un commento in sé. Questo è un heredoc che viene reindirizzato al comando NOP come una stringa multilinea. La virgoletta singola è importante per disabilitare la risoluzione di variabili e comandi.
Nux,

1
@Freek ha bisogno di aggiungere spazio
mazs

Ho provato questo in un semplice script bash che gira attraverso la sua riga shebang, #! / Bin / bash in Debian e non è riuscito. Sto provando ogni risposta su questa pagina e tutti hanno fallito fino a quando non sono arrivato a quello qui sotto. Dal momento che hanno fallito, li sto votando verso il basso e sto votando a favore di quello che funziona correttamente.
PyTis,

1
Buoni test nel tuo esempio. Il comando :non è necessario. Inizia con <<.
Wisbucky,

34

Sto aggiornando questo post in base a commenti e altre risposte, quindi i commenti precedenti al 22 maggio 2020 potrebbero non essere più applicabili.

Bash non fornisce una sintassi integrata per i commenti su più righe ma ci sono hack che usano la sintassi bash esistente che "sembra funzionare ora".

Personalmente penso che il più semplice (cioè meno rumoroso, meno strano, più facile da digitare, più esplicito) sia usare un HEREDOC citato, ma rendere ovvio ciò che stai facendo e usare lo stesso marcatore HEREDOC ovunque:

<<'### BLOCK COMMENT'
line 1
line 2

line 3
line 4
### BLOCK COMMENT

La virgoletta singola del marcatore HEREDOC evita alcuni effetti collaterali dell'analisi shell, come strane sostituzioni che potrebbero causare arresti anomali o output e persino l'analisi del marcatore stesso. Quindi le virgolette singole ti danno più libertà sul marker di commento aperto-chiuso. Ad esempio, ciò che segue usa un triplo hash che suggerisce un commento multilinea in bash. Ciò causerebbe l'arresto anomalo dello script se le singole virgolette fossero assenti. Anche se lo rimuovessi ###, FOO{}si bloccherebbe lo script (o causerebbe la stampa di una sostituzione errata in set -ecaso contrario) se non fosse per le virgolette singole:

set -e

<<'### BLOCK COMMENT'
something something ${FOO{}} something
more comment
### BLOCK COMMENT

ls

Ovviamente potresti semplicemente usare

set -e

<<'###'
something something ${FOO{}} something
more comment
###

ls

ma l'intento è decisamente meno chiaro per un lettore che non ha familiarità con questo trucco.

Oggi qualsiasi buon editor ti consente di premere ctrl- / o simili, per annullare / commentare la selezione. Tutti lo capiscono sicuramente:

# something something ${FOO{}} something
# more comment
# yet another line of comment

sebbene sia vero, ciò non è altrettanto conveniente del commento di blocco sopra se si desidera riempire nuovamente i paragrafi.

Esistono sicuramente altre tecniche, ma non sembra esserci un modo "convenzionale" per farlo. Sarebbe bello se ###>e ###<potesse essere aggiunto a bash per indicare l'inizio e la fine del blocco dei commenti, sembra che potrebbe essere piuttosto semplice.


1
Ah, questo è abbastanza facile / pulito da ricordare!
Thamme Gowda,

1
Come indicato nella precedente risposta, oltre ai backquotes, anche la sequenza $ (...) verrà espansa in quanto entrambi i moduli sostituiscono i comandi.
Perl Ancar,

"Entrambi sono hack in modo da poter rompere gli script in futuro." Potresti approfondire questo? Sebbene gli hacks semanticamente, sintatticamente sono validi e non dovrebbero rompersi in futuro, a meno che bash non decida di impazzire e rompa gli heredocs.
Perl Ancar,

@perlancar Se siamo d'accordo che gli hack sono soluzioni che usano una funzionalità di lingua / lib completamente estranea al problema (come usare un heredoc per un commento o usare un parametro su un comando do-nothing come true), allora anche se non lo fanno 'a rischio di rottura (l'approccio ereditario no, ma la versione in due punti lo fa), 1) gli hack offuscano ancora l'intento: senza la prima riga che accenna al commento multilinea, la maggior parte si griderebbe la testa chiedendosi cosa stia facendo quel codice; e 2) hanno angoli scuri inaspettati (come dover raddoppiare una citazione, citare il marker ereditario in alcuni casi, ecc.).
Oliver,

@Oliver: se non quotato, le variabili possono avere effetti collaterali negativi. Immaginate di avere incorporato nel vostro heredoc -comment una stringa come ${FOO:=bar}o ${FOO{}}. Il primo potrebbe avere l'effetto collaterale di creare e impostare la variabile FOO, il secondo genererà un errore di sostituzione errato; entrambi gli effetti che non ti aspetteresti da un vero commento.
user1934428

24

Dopo aver letto le altre risposte qui ho trovato il seguito, che IMHO chiarisce davvero che è un commento. Particolarmente adatto per informazioni sull'utilizzo in-script:

<< ////

Usage:
This script launches a spaceship to the moon. It's doing so by 
leveraging the power of the Fifth Element, AKA Leeloo.
Will only work if you're Bruce Willis or a relative of Milla Jovovich.

////

Come programmatore, la sequenza di barre si registra immediatamente nel mio cervello come commento (anche se le barre vengono normalmente utilizzate per i commenti di linea).

Certo, "////"è solo una stringa; il numero di barre nel prefisso e nel suffisso deve essere uguale.


3
Ho quasi perso ilUsage:
RNA

Ottima aggiunta alla risposta sopra. Onestamente, penso che avresti potuto modificare la risposta di cui sopra e aggiungerla, invece di rispondere separatamente.
PyTis il

Ci sono alcune risposte "sopra" (a seconda del tuo ordinamento). E, rispondendo separatamente, volevo spiegare la logica alla base della stringa che ho scelto.
Noamtm,

<< EOF ... EOF
Mingzhi,

5

qual è la tua opinione su questo?

function giveitauniquename()
{
  so this is a comment
  echo "there's no need to further escape apostrophes/etc if you are commenting your code this way"
  the drawback is it will be stored in memory as a function as long as your script runs unless you explicitly unset it
  only valid-ish bash allowed inside for instance these would not work without the "pound" signs:
  1, for #((
  2, this #wouldn't work either
  function giveitadifferentuniquename()
  {
    echo nestable
  }
}

ciao, non era inteso come una domanda, piuttosto che una risposta alla domanda originale
Imre

IMO non buono. Richiede che il commento sia analizzabile come codice shell, il che è piuttosto restrittivo.
user1934428

3

Ecco come faccio commenti multilinea in bash.

Questo meccanismo ha due vantaggi che apprezzo. Uno è che i commenti possono essere nidificati. L'altro è che i blocchi possono essere abilitati semplicemente commentando la riga iniziale.

#!/bin/bash
# : <<'####.block.A'
echo "foo {" 1>&2
fn data1
echo "foo }" 1>&2
: <<'####.block.B'
fn data2 || exit
exit 1
####.block.B
echo "can't happen" 1>&2
####.block.A

Nell'esempio sopra il blocco "B" è commentato, ma le parti del blocco "A" che non sono il blocco "B" non sono commentate.

L'esecuzione di questo esempio produrrà questo output:

foo {
./example: line 5: fn: command not found
foo }
can't happen

3

Ho provato la risposta scelta, ma ho scoperto che quando eseguivo uno script shell con esso, l'intera cosa veniva stampata sullo schermo (simile a come i quaderni di Giove stampavano tutto tra '''xx'''virgolette) e alla fine c'era un messaggio di errore. Non stava facendo nulla, ma: spaventoso . Poi mi sono reso conto durante la modifica che le virgolette singole possono estendersi su più righe. Quindi .. consente di assegnare il blocco a una variabile.

x='
echo "these lines will all become comments."
echo "just make sure you don_t use single-quotes!"

ls -l
date

'

Non c'è bisogno di assegnarlo a una variabile, che è un effetto collaterale che non ci aspetteremmo da un 'commento'. Sostituisci x=con a : e avrai lo stesso effetto senza effetti collaterali. L'unico inconveniente è che il commento non deve contenere una sola citazione. Ecco perché preferisco l'uso di un heredoc citato: con questo, il commentatore può scegliere una stringa di terminazione adatta a suo piacimento.
user1934428

2

Soluzione semplice, non molto intelligente:

Blocca temporaneamente una parte di uno script:

if false; then
    while you respect syntax a bit, please
    do write here (almost) whatever you want.
    but when you are
    done # write
fi

Una versione un po 'sofisticata:

time_of_debug=false # Let's set this variable at the beginning of a script

if $time_of_debug; then # in a middle of the script  
    echo I keep this code aside until there is the time of debug!
fi

-2

# Mi piace la pigrizia e la semplicità. Userei # con una soluzione alternativa divertente:

1 PREMERE:] trova ctrl + F o cmd + F o qualsiasi altra cosa [per attivare la funzionalità di ricerca

2 usa un regex nel campo find come: (^.+)

3 sostituisci con: # $1o se preferisci#$1


# Nota: potresti non avere i tre passaggi nel tuo editor. In tal caso, utilizzare uno strumento regex online (non è possibile suggerire uno qui per motivi di politica):

  1. Seleziona, copia il testo ovunque ti trovi e incollalo nello strumento regex online
  2. Utilizzare (^.+)come regex e #$1o #\1come schemi di sostituzione
  3. Seleziona, copia il testo e incollalo nel punto in cui hai iniziato

# Goditi i tuoi hash!


In questi giorni molti editor hanno il tasto di scelta rapida ctrl+/che attiva o disattiva i commenti, anche per più righe. È anche in grado di cambiare il carattere del commento in base alla lingua che si sta utilizzando.
ninMonkey,
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.