Quel est le cas d’utilisation de noop dans bash?

J’ai cherché noop dans bash (:), mais n’a pas pu trouver de bonnes informations. Quel est le but exact ou le cas d’utilisation de cet opérateur?

J’ai essayé de suivre et ça marche comme ça pour moi:

[mandy@root]$ a=11 [mandy@root]$ b=20 [mandy@root]$ c=30 [mandy@root]$ echo $a; : echo $b ; echo $c 10 30 

S’il vous plaît laissez-moi savoir, tout cas d’utilisation de cet opérateur en temps réel ou tout endroit où il est obligatoire de l’utiliser.

C’est là plus pour des raisons historiques. Le double point : est exactement équivalent à true . Il est traditionnel d’utiliser true lorsque la valeur de retour est importante, par exemple dans une boucle infinie:

 while true; do echo 'Going on forever' done 

Il est traditionnel d’utiliser : lorsque la syntaxe du shell nécessite une commande mais que vous n’avez rien à faire.

 while keep_waiting; do : # busy-wait done 

The : builtin date du shell Thompson , il était présent dans Unix v6 . : était un indicateur d’étiquette pour l’ goto du shell Thompson. Le libellé pourrait être n’importe quel texte, donc : doublé en tant qu’indicateur de commentaire (s’il n’y a pas de goto comment , alors : comment est un commentaire). La coquille de Bourne n’a pas été retenue mais conservée goto

Un idiome commun qui utilise : est : ${var=VALUE} , qui définit var à VALUE s’il était désactivé et ne fait rien si var était déjà défini. Cette construction n’existe que sous la forme d’une substitution de variable, et cette substitution de variable doit faire partie d’une commande d’une manière ou d’une autre: une commande no-op sert bien.

Voir aussi À quoi sert le côlon intégré? .

Je l’utilise pour les déclarations if lorsque je commente tout le code. Par exemple, vous avez un test:

 if [ "$foo" != "1" ] then echo Success fi 

mais vous souhaitez commenter temporairement tout ce qui est contenu dans:

 if [ "$foo" != "1" ] then #echo Success fi 

Ce qui amène bash à donner une erreur de syntaxe:

 line 4: syntax error near unexpected token `fi' line 4: `fi' 

Bash ne peut pas avoir de blocs vides (WTF). Donc, vous ajoutez un no-op:

 if [ "$foo" != "1" ] then #echo Success : fi 

ou vous pouvez utiliser le no-op pour commenter les lignes:

 if [ "$foo" != "1" ] then : echo Success fi 

Vous utiliseriez : pour fournir une commande qui réussit mais ne fait rien. Dans cet exemple, la commande “verbosity” est désactivée par défaut, en la définissant sur : L’option ‘v’ l’allume.

 #!/bin/sh # example verbosity=: while getopts v OPT ; do case $OPT in v) verbosity=/bin/realpath ;; *) exit "Cancelled" ;; esac done # `$verbosity` always succeeds by default, but does nothing. for i in * ; do echo $i $($verbosity $i) done $ example file $ example -v file /home/me/file 

Si vous utilisez set- e alors || : || : est un excellent moyen de ne pas quitter le script si une défaillance se produit (cela le fait explicitement passer).

Parfois, les clauses sans opération peuvent rendre votre code plus lisible.

Cela peut être une question d’opinion, mais voici un exemple. Supposons que vous ayez créé une fonction qui fonctionne en prenant deux chemins Unix. Il calcule le «chemin de changement» nécessaire pour cd d’un chemin à un autre. Vous placez une ressortingction sur votre fonction que les chemins doivent tous deux commencer par un «/» OU les deux ne doivent pas.

 function chgpath() { # toC, fromC are the first characters of the argument paths. if [[ "$toC" == / && "$fromC" == / ]] || [[ "$toC" != / && "$fromC" != / ]] then true # continue with function else return 1 # Skip function. fi 

Certains développeurs voudront supprimer le non-op mais cela signifierait nier le conditionnel:

 function chgpath() { # toC, fromC are the first characters of the argument paths. if [[ "$toC" != / || "$fromC" == / ]] && [[ "$toC" == / || "$fromC" != / ]] then return 1 # Skip function. fi 

Maintenant, à mon avis, ce n’est pas si clair dans la clause if les conditions dans lesquelles vous voulez ignorer la fonction. Pour éliminer le non-op et le faire clairement, vous voudriez déplacer la clause if de la fonction:

  if [[ "$toC" == / && "$fromC" == / ]] || [[ "$toC" != / && "$fromC" != / ]] then cdPath=$(chgPath pathA pathB) # (we moved the conditional outside) 

Cela a l’air mieux, mais plusieurs fois nous ne pouvons pas le faire; nous voulons que la vérification soit faite à l’intérieur de la fonction.

Alors, à quelle fréquence cela se produit-il? Pas très souvent. Peut-être une ou deux fois par an. Il arrive assez souvent que vous deviez en être conscient. Je ne crains pas de l’utiliser lorsque je pense que cela améliore la lisibilité de mon code (indépendamment de la langue).

Deux des miens

Intégrer des commentaires POD

Une application assez géniale de : consiste à incorporer des commentaires POD dans des scripts bash , afin de générer rapidement des pages de manuel. Bien sûr, on réécrirait éventuellement tout le script en Perl 😉

Liaison de la fonction d’exécution

Ceci est une sorte de modèle de code pour les fonctions de liaison au moment de l’exécution. Fi, avoir une fonction de débogage pour faire quelque chose uniquement si un certain drapeau est défini:

 #!/bin/bash # noop-demo.sh shopt -s expand_aliases dbg=${DBG:-''} function _log_dbg { echo >&2 "[DBG] $@" } log_dbg_hook=':' [ "$dbg" ] && log_dbg_hook='_log_dbg' alias log_dbg=$log_dbg_hook echo "Testing noop alias..." log_dbg 'foo' 'bar' 

Vous obtenez:

 $ ./noop-demo.sh Testing noop alias... $ DBG=1 ./noop-demo.sh Testing noop alias... [DBG] foo bar 

Une utilisation est comme les commentaires multilignes, ou pour commenter une partie de votre code à des fins de test en l’utilisant conjointement avec un fichier ici.

 : < < 'EOF' This part of the script is a commented out EOF 

N'oubliez pas d'utiliser des guillemets autour de EOF pour que tout code à l'intérieur ne soit pas évalué, comme $(foo) . Il pourrait également être utile d'utiliser un nom de terminaison intuitif comme NOTES , SCRATCHPAD ou TODO .

Ignorer les arguments d’ alias

Parfois, vous voulez avoir un alias qui ne prend aucun argument. Vous pouvez le faire en utilisant:

 > alias alert_with_args='echo hello there' > alias alert='echo hello there;:' > alert_with_args blabla hello there blabla > alert blabla hello there 

Un peu lié à cette réponse , je trouve cette opération plutôt pratique pour pirater des scripts polyglottes . Par exemple, voici un commentaire valide à la fois pour bash et pour vimscript:

 ":" # this is a comment ":" # in bash, ':' is a no-op and '#' starts a comment line ":" # in vimscript, '"' starts a comment line 

Bien sûr, nous avons peut-être aussi bien utilisé la true , mais : être un signe de ponctuation et non un mot anglais sans importance indique clairement qu’il s’agit d’un jeton de syntaxe.


Pour ce qui est de savoir pourquoi quelqu’un ferait une chose aussi délicate qu’écrire un script polyglotte (en plus d’être cool): il s’avère utile dans des situations où l’on écrit normalement plusieurs fichiers de script dans plusieurs langues différentes, le fichier X faisant référence au fichier Y

Dans une telle situation, combiner les deux scripts dans un seul fichier polyglotte évite tout travail dans X pour déterminer le chemin vers Y (il s’agit simplement de "$0" ). Plus important encore, cela facilite le déplacement ou la dissortingbution du programme.

  • Un exemple courant. Il existe un problème bien connu et de longue date avec les shebangs: la plupart des systèmes (y compris Linux et Cygwin) ne permettent de transmettre qu’un seul argument à l’interpréteur. Le shebang suivant:

     #!/usr/bin/env interpreter --load-libA --load-libB 

    lancera la commande suivante:

     /usr/bin/env "interpreter --load-libA --load-libB" "/path/to/script" 

    et pas l’intention:

     /usr/bin/env interpreter --load-libA --load-libB "/path/to/script" 

    Ainsi, vous finirez par écrire un script wrapper, tel que:

     #!/usr/bin/env sh /usr/bin/env interpreter --load-libA --load-libB "/path/to/script" 

    C’est ici que la polyglossie entre en scène.

  • Un exemple plus spécifique. Une fois, j’ai écrit un script bash qui, entre autres choses, invoquait Vim. Je devais donner à Vim une configuration supplémentaire, ce qui pourrait être fait avec l’option --cmd "arbitrary vimscript command here" . Cependant, cette configuration était importante, de sorte que l’inclure dans une chaîne aurait été terrible (si possible). Par conséquent, une meilleure solution consistait à l’écrire in extenso dans un fichier de configuration, puis à faire en sorte que Vim lise ce fichier avec -S "/path/to/file" . J’ai donc fini avec un fichier polyglot bash / vimscript.