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.
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? .
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
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
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).
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
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
.
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).
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
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.