Commentaires sur les scripts de shell multilignes - comment ça marche?

92

Récemment, je suis tombé sur un type de commentaire multiligne que je n’avais jamais vu auparavant - voici un exemple de script:

echo a
#
: aaa 
: ddd 
#
echo b

Cela semble fonctionner, même la vimsyntaxe le met en évidence. Comment appelle-t-on ce style de commentaire et comment trouver plus d’informations à ce sujet?

Wiesław Herr
la source
1
Et si vous encapsuliez votre code dans une fonction pour commenter? CommentedOutBlock() { echo "test"; }
Buksy

Réponses:

135

Ce n'est pas un commentaire sur plusieurs lignes. #est un commentaire d'une seule ligne. :(deux points) n’est pas du tout un commentaire, mais plutôt une commande intégrée du shell, qui est essentiellement un NOP , une opération null qui ne fait rien, sauf renvoyer true, comme true(et donc mettre $?à 0 comme effet secondaire). Cependant, puisqu'il s'agit d'une commande, il peut accepter des arguments et, comme il l'ignore, il se comporte généralement superficiellement comme un commentaire. Le principal problème de ce problème est que les arguments sont encore développés, ce qui entraîne de nombreuses conséquences imprévues. Les arguments sont toujours affectés par des erreurs de syntaxe, les redirections sont toujours effectuées, elles : > fileseront donc tronquées fileet les : $(dangerous command)substitutions seront toujours exécutées.

Le moyen le moins surprenant d’insérer des commentaires dans des scripts shell est l’utilisation de #. Tenez-vous en à cela même pour les commentaires sur plusieurs lignes. N'essayez jamais de (ab) utiliser :pour des commentaires. Il n’existe dans le shell aucun mécanisme de commentaire multi-lignes dédié analogue à la /* */forme étoile-barre oblique dans des Clangages similaires.


Par souci d’exhaustivité, mais pas parce que cela est recommandé, je mentionnerai qu’il est possible d’utiliser ici des documents pour faire des "commentaires" multilignes:

: <<'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
jw013
la source
29
+1 très important pour garder les guillemets simples sur la <<ligne - cela désactive la substitution et l'expansion.
Glenn Jackman
4
Et comme note supplémentaire, le fait de remplir des scripts de shell avec :des éléments qui devraient être des commentaires entraînera une consommation supplémentaire de RAM / CPU. Cela ne fera pas l'affaire pour des choses simples sur votre bureau, mais s'il s'agit de quelque chose exécuté des centaines ou des milliers de fois par seconde, vous ne ferez rien, très vite .
bahamat
3
@bahamat: si vous exécutez quelque chose des centaines ou des milliers de fois par seconde, j'espère que vous ne l'écrirez pas en shell ... = /
7heo.tk
1
Parfois, utiliser l'utilitaire null pour plusieurs lignes de texte peut être utile. Démarrer le commentaire avec : <<=cutpermet d' écrire POD dans des scripts shell, voir cet exemple pour plus de détails . Cela permet d’utiliser perldoc script.sh. Cependant, le commentaire multiligne indiqué dans cette réponse est quelque chose qui doit absolument être un bloc de commentaires (chaque ligne commençant par # ).
basic6
Voici une bonne discussion sur heredocs, utilisé pour les commentaires et autres cas d'utilisation intéressants (même avec la génération de script dynaimc): tldp.org/LDP/abs/html/here-docs.html#EX71C
bguiz
28

Ce n'est pas un style de commentaire. la :commande intégrée ne fait absolument rien; on en abuse pour avoir commenté ici.

$ help :
:: :
    Null command.

    No effect; the command does nothing.

    Exit Status:
    Always succeeds.
Ignacio Vazquez-Abrams
la source
25

Dans les premiers coquillages, les deux points étaient le seul moyen de créer des commentaires.

Cependant, ce n'est pas un vrai commentaire, car la ligne est analysée de la même manière que toute autre commande, ce qui peut avoir des effets secondaires. Par exemple:

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

: $(command) # executes 'command'

(Parfois, les deux points sont utilisés uniquement dans le but d'invoquer ces effets secondaires, mais ils ne servent alors pas de commentaire.)

Il est parfois pratique d'utiliser les deux points pour commenter une section de script:

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

C’est un gain de temps considérable par rapport à chaque ligne précédente #, en particulier si la mise en commentaire n’est que temporaire.

Chris FA Johnson
la source
2
Cette méthode de commentaire entre guillemets ne fonctionne sur aucune section de script qui utilise elle-même des guillemets. Et si vous utilisez des guillemets aussi près que vous le devriez, cela signifie que vous aurez des guillemets simples légitimes parsemés tout au long du script. Il est tellement plus simple d’utiliser tout éditeur décent qui vous permet de bloquer les commentaires ligne par ligne.
Jw013
Vous avez parfaitement raison, cela ne fonctionnera que s'il n'y a pas de guillemets simples dans la section citée. Cependant, un script ne doit pas nécessairement comporter beaucoup de guillemets simples. En parcourant quelques-uns de mes scripts, je les trouve relativement rares et beaucoup pourraient être remplacés par des guillemets.
Chris FA Johnson
Le choix de guillemets simples ou de guillemets doubles ne devrait guère être influencé par quelque chose d'aussi trivial et non pertinent que de savoir si le texte de votre script est lui-même une chaîne valide entre guillemets simples. Les guillemets simples sont utilisés pour empêcher les extensions, tandis que les guillemets doubles autorisent certaines extensions et nécessitent une analyse syntaxique supplémentaire. Ce sont les vrais critères pour déterminer lequel utiliser.
jw013
C'est de loin la manière la plus chic de le faire. Idéal pour les petits blocs de documentation. Je l'aime mieux que /* */et euh, ne me lancez pas <!-- -->!
alex grey
1

Si votre commentaire se trouve à la fin du script, vous pouvez le faire comme ceci:

#!/bin/sh
echo 'hello world'
exec true
we can put whatever we want here
\'\"\$\`!#%&()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
abcdefghijklmnopqrstuvwxyz{|}~
Steven Penny
la source