Quelle est l'utilité de noop [:] à bash?

j'ai cherché noop à bash (:), mais je n'ai pu trouver aucune bonne information. Quelle est la fonction exacte ou en 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, toute utilisation de cet opérateur en temps réel ou à tout endroit où il est obligatoire de l'utiliser.

84
demandé sur Tshepang 2012-09-13 14:55:05

9 réponses

c'est plus pour des raisons historiques. Le bâtiment : 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

le bâtiment : date de tout retour au Thompson shell , il était présent dans Unix v6 . : était un indicateur d'étiquette pour la déclaration goto de Thompson shell. L'étiquette pourrait être n'importe quel texte, donc : doublé comme un indicateur de commentaire (s'il n'y a pas de goto comment , alors : comment est effectivement un commentaire). Le Bourne shell n'avait pas goto mais conservait : .

un langage courant qui utilise : est : ${var=VALUE} , qui fixe var à VALUE s'il était débranché et ne fait rien si var était déjà fixé. Cette construction n'existe que sous la forme d'une substitution de variable, et cette substitution de variable doit faire partie d'une commande en quelque sorte: une commande no-op sert bien.

Voir aussi Quel est le but de la construction du côlon? .

123
répondu Gilles 2017-04-13 12:36:27

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 voulez commenter temporairement tout ce qu'il contient:

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

qui fait que bash donne une erreur de syntaxe:

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

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

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

ou vous pouvez utiliser le no-op à commentez les lignes:

if [ "$foo" != "1" ]
then
    : echo Success
fi
11
répondu Stephen Ostermiller 2017-12-07 10:32:02

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 positionnant à : . 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  
6
répondu Mark 2016-05-12 00:11:17

si vous utilisez set- e puis || : est un excellent moyen de pas quitter le script si un échec se produit (il le fait passer explicitement).

6
répondu Crisfole 2016-07-12 15:04:31

deux des miennes.

Incorporer la GOUSSE de commentaires

une application assez funky de : est pour commentaires pod d'intégration dans les scripts de bash , de sorte que les pages de manuel peuvent être générées rapidement. Bien sûr, on pourrait éventuellement réécrire tout le script en Perl ; -)

liaison des fonctions D'exécution

c'est une sorte de motif de code pour les fonctions de liaison à l'exécution. F. i., avoir un débogage fonction pour faire quelque chose seulement si un certain drapeau est placé:

#!/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
3
répondu sphakka 2017-08-10 09:59:40

une utilisation est comme commentaires multilignes, ou pour commenter une partie de votre code à des fins de test en l'utilisant en conjonction avec un fichier here.

: << 'EOF'

This part of the script is a commented out

EOF

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

3
répondu Geoffrey Ritchey 2017-12-09 12:19:57

parfois, les clauses "no-op" peuvent rendre votre code plus lisible.

Qui peut être une question d'opinion, mais voici un exemple. Supposons que vous avez créé une fonction qui fonctionne en prenant deux chemins unix. Il calcule le 'chemin de changement' nécessaire pour cd d'un chemin à l'autre. Vous placez une restriction sur votre fonction que les chemins d'accès doivent commencer par un '/' OU les deux, 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 no-op mais cela signifierait la négation du 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-n'est pas si clair de la clause si-les conditions dans lesquelles vous voudriez sauter faire la fonction. Pour éliminer le no-op et le faire clairement, vous voudriez déplacer le si-clause hors de la fonction:

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

cela semble mieux, mais souvent nous ne pouvons pas faire cela; nous voulons que le contrôle soit fait à l'intérieur de la fonction.

donc combien de fois cela se produit? Pas très souvent. Peut-être une fois ou deux fois par an. Cela arrive assez souvent, que vous devriez en être conscient. Je n'ai pas hésiter à l'utiliser quand je pense qu'il améliore la lisibilité de mon code (quelle que soit la langue).

2
répondu Bitdiot 2014-11-05 14:59:19

ignorer alias arguments

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
2
répondu Ulysse BN 2017-07-20 19:54:28

un peu apparenté à cette réponse , je trouve CE no-op plutôt pratique pour hacker polyglotte scripts. 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 utilisé true tout aussi bien, mais : étant un signe de ponctuation et non un mot anglais non pertinent, il est clair qu'il s'agit d'un jeton de syntaxe.


comme pour pourquoi quelqu'un ferait-il une chose aussi délicate que d'écrire un script polyglotte (en plus d'être cool): cela s'avère utile dans les situations où nous écririons normalement plusieurs fichiers de script dans plusieurs langues différentes, avec le fichier X se référant au fichier Y .

dans une telle situation, la combinaison des deux scripts dans un seul fichier polyglotte évite tout travail dans X pour déterminer le chemin vers Y (il est tout simplement ""1519110920"" ). Plus important encore, il est plus pratique de se déplacer ou de distribuer le programme.

  • un exemple courant. il y a un problème bien connu de longue date avec les shebangs: la plupart des systèmes (y compris Linux et Cygwin) ne permettent que un argument à passer à l'interpréteur. Le shebang suivant:

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

    tirera les suivants commande:

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

    et non la destination:

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

    ainsi, vous finiriez par écrire un script d'emballage, tel que:

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

    c'est ici que polyglossia entre en scène.

  • un exemple plus précis. j'ai écrit un jour un scénario bash qui, entre autres choses, invoquait Vim. J'avais besoin de donner Vim une configuration supplémentaire, qui pourrait être fait avec l'option --cmd "arbitrary vimscript command here" . Cependant, cette configuration était substantielle, de sorte que l'incliner dans une chaîne aurait été terrible (si jamais possible). Par conséquent, une meilleure solution était de l'écrire in extenso dans un fichier de configuration, puis de faire lire à Vim ce fichier avec -S "/path/to/file" . J'ai donc fini avec un fichier polyglot bash/vimscript.

1
répondu Maëlan 2018-08-06 16:05:03