Ce qui est plus idiomatique dans un script bash: `|| true` ou `|| : `?

36

Je ne fais pas beaucoup de scripts shell, j'ai donc été un peu surpris de lire la documentationgit submodule et de voir la syntaxe utilisée dans cette documentation:

Un retour non nul de la commande dans n'importe quel sous-module provoque l'arrêt du traitement. Cela peut être annulé en ajoutant || :à la fin de la commande.

Je devais rechercher || :un raccourci pour forcer une commande à quitter correctement. Chaque fois que j'ai eu à faire une commande de sortie avec succès, j'ai utilisé || true. Est || :considéré comme plus idiomatique?

Mark Rushakoff
la source
Il est à noter que ||:(sans espace) est également valide dans bash. Il fait la même chose que || :ou || true.
Bruno Bronosky

Réponses:

38

truen'a pas été construit dans le shell Bourne. :c'était toujours le cas (c'était le moyen de saisir les commentaires avant d' #être introduit).

Cela, et parce qu'il est plus court type est probablement la principale raison les gens préfèrent :plus true.

Notez une autre différence dans les shells POSIX (pour bash, uniquement en mode POSIX): while trueest une commande interne régulière (ne doit même pas être intégrée), :est une commande spéciale . Cela a quelques implications, dont la plupart n'auront probablement aucun impact dans ce cas particulier:

  • Si une :commande échoue, y compris en raison d’une redirection manquée, le shell se ferme. En pratique, cela ne fera probablement pas de différence si vous ne transmettez pas les redirections à:

    $ sh -c ': > /   ; echo HERE'
    sh: 1: cannot create /: Is a directory
    $ sh -c 'true > /; echo HERE'
    sh: 1: cannot create /: Is a directory
    HERE
  • dans var=value :, varreste défini sur valueaprès les :retours, pas dans le cas de true:

    $ var=1; var=2 :   ; echo "$var"
    2
    $ var=1; var=2 true; echo "$var"
    1

Notez également que || truefonctionne dans les coquilles des rcet cshfamilles mais pas || :(mais ne pas annuler set -een csh).

|| :n'est pas la même chose que :. Cela signifie ou s'exécute :autrement (c'est-à-dire si le pipeline précédent échoue).

set -e
false

Causerait la coquille de sortie en raison de set -eet falsea un statut de sortie non nul (échec). L' set -eeffet est annulé si la commande qui renvoie un état de sortie différent de zéro est utilisée comme condition, comme dans:

if false; then ...
while false; do ...
false && : ...
false || : ...

false && :n'annule que set -e. false || :annule set -eet définit le statut de sortie sur 0est donc plus idiomatique de dire que nous voulons ignorer un code de sortie d'échec de la commande. La plupart diraient que || truec'est plus lisible (traduit plus clairement l'intention).

Stéphane Chazelas
la source
5
&& :est génial, y a-t-il des documents ou des lectures supplémentaires à ce sujet? Google me manque pour essayer de trouver ce genre de mots-clés…
Ian Bytchek
5

Généralement, en bash, le côlon :et trueest équivalent.

Est || : considéré comme plus idiomatique?

Je pense que cela dépend du contexte .

Si vous voulez un return value, ou un conditionest toujours vrai, vous devez utiliser truemot-clé, cela rendra votre code plus clair et indiquera au spectateur que vous souhaitez souligner la valeur true , c'est-à-dire:

while true; do something

ou

<commnad>
RETURN_VALUE= $? || true

Et si vous ne voulez rien faire , ou NOPen shell, vous devez utiliser le côlon:

if condition
then
    : # DO NOTHING HERE
else
    do something
fi 

ou

while conditon
do
    : # DO NOTHING HERE
done
cuonglm
la source
5

La plupart de ces réponses ne répondent pas à l'utilisation la plus courante de :.

Premièrement, cette discussion ne concerne aucun shell autre qu'un dérivé de Bourne shell ( sh). Cela dit, toutes les coquilles dérivés Bourne voir trueet :que la même chose. Les programmeurs étaient encouragés à utiliser à la :place de true, car :est toujours intégré, alors qu’il existait des cas où il truen’était pas toujours intégré.

:a deux utilisations. Ce n'est pas un synonyme pour #, mais il a une fonction différente. Lors du débogage de votre script sous a set -x, les lignes où #est utilisé sont supprimées par l’analyseur et totalement ignorées, alors que les lignes avec :sont analysées et évaluées. Ceci est vraiment utile pour le débogage car -xces lignes sont affichées et leur valeur après évaluation est affichée. C'est comme mettre printdans votre code des déclarations qui ne s'affichent qu'en -xmode. Soyez prudent avec les valeurs suivantes :car elles sont du code réel et les effets secondaires peuvent affecter votre programme.

cdr
la source
1
Quelle est la deuxième utilisation?
Peter Mortensen