J'ai piraté beaucoup de scripts shell, et parfois les choses les plus simples me déconcertent. Aujourd'hui, j'ai rencontré un script qui faisait un usage intensif de la commande :
intégrée de bash (deux points).
La documentation semble assez simple:
: (a colon) : [arguments]
Ne rien faire à part développer des arguments et effectuer des redirections. Le statut de retour est zéro.
Cependant, je n’avais auparavant vu cela que dans des démonstrations d’extension de coque. Le cas d'utilisation du script que j'ai rencontré utilisait beaucoup cette structure:
if [ -f ${file} ]; then
grep some_string ${file} >> otherfile || :
grep other_string ${file} >> otherfile || :
fi
Il y avait en fait des centaines de greps, mais ils sont plus ou moins identiques. Aucune redirection d'entrée / sortie n'est présente à part la structure simple ci-dessus. Aucune valeur de retour n'est vérifiée plus tard dans le script.
Je lis ceci comme une construction inutile qui dit "ou ne fait rien". A quoi bon mettre fin à ces greps avec "ou ne rien faire"? Dans quel cas cette construction entraînerait-elle un résultat différent de celui de simplement laisser tomber || :
toutes les instances?
:
une alternative àtrue
. Peuterrexit
- être est-il défini et l'auteur se fiche du statut de sortie de certaines commandes.Réponses:
Il semble que les
:
s de votre script soient utilisés à la place detrue
. S'ilgrep
ne trouve pas de correspondance dans le fichier, un code de sortie différent de zéro sera renvoyé. Comme jw013 le mentionne dans un commentaire, s'ilerrexit
est défini, probablement par-e
sur la ligne shebang, le script se terminera si l'un desgrep
s ne réussit pas à trouver une correspondance. Clairement, ce n’est pas ce que l’auteur voulait, c’est pourquoi il a ajouté|| :
pour que le statut de sortie de cette commande composée soit toujours égal à zéro, comme le plus courant (selon mon expérience)|| true
/|| /bin/true
.la source
true
place, mais l'intention sémantique est beaucoup plus claire avectrue
.:
est plus approprié lorsqu'un NOP explicite est souhaité.:
au lieu detrue
parce qu’il:
estbash
intégré àtrue
un système binaire compilé avec plus de surcharge. généralement, je l'utilisetrue
parce que le code est plus lisible (de même, je préfère utiliser à lasource
place de.
).La fonction
:
intégrée est également utile avec l’extension de shell «attribuer des valeurs par défaut» de Bash, où l’expansion est souvent utilisée uniquement pour l’effet secondaire et où la valeur développée est supprimée:la source
Je peux penser à deux endroits que j'ai utilisés
:
dans le passé.C'est une boucle pour toujours.
Mettez une fonction stub, juste pour obtenir un flux de contrôle de niveau supérieur correct.
Une utilisation que j’ai vue à l’époque: au lieu d’une ligne
#!/bin/sh
(ou autre), vous verriez une:
ligne. Certains noyaux Real Unix ou shells Unix plus anciens utilisent ce terme pour signifier "Je suis un script shell, je l'ai exécuté". Si je me souviens bien, csh venait juste de faire son apparition en tant que shell interactif commun.la source
:
est très étrange. J'ai constaté que le script s'exécute bien avecsh
. où, comme lorsque vous démarrez le script sans shebang ..., il essaie de l'exécuter avec n'importe quel shell en cours d'exécution (ainsi, si vous l'exécutez, essayezbash
de l'exécuter commebash
si vous l'aviezcsh
ensuite, il essayait de l'exécuter en tant quecsh
).L'
:
intégré était déjà dans le shell Thompson - il est documenté pour Unix V6 en 1975. Dans le shell Thompson,:
indique une étiquette pour lagoto
commande. Si vous n'avez jamais essayé d'appelergoto
sur une ligne commençant par:
, cette ligne était en réalité un commentaire.Le shell Bourne , ancêtre des shell Bourne / POSIX tels que nous les connaissons, n’a jamais eu de
goto
réponse connue, mais conservé:
comme commande no-op (il était déjà présent dans Unix V7 ).la source
J'ai extrait une ancienne référence: "L'environnement de programmation UNIX" (c) 1984 de Kernighan et Pike.
Page 147 (Programmation Shell) dit ceci:
la source
true
c’est désormais un shell intégré à de nombreux systèmes.Je semble me souvenir que les premières versions du shell n’avaient pas de syntaxe de commentaire. Une ligne commençant par
:
(qui aurait probablement été un exécutable réel, similaire à/bin/true
) aurait été la meilleure alternative.Voici une page de manuel relative à l’ancienne coquille Thompson (aucune relation); il n'y a aucune mention de syntaxe de commentaire.
la source
:
était en fait un indicateur d'étiquette pour lagoto
commande, dans un ancien shell (je ne sais pas lequel). Une étiquette: something
pourrait en effet être utilisée comme commentaire s’il n’y avait pas de correspondancegoto
. La pratique a collé même après avoirgoto
disparu.":" est pratique pour le débogage.
Si vous exécutez normalement la fonction de débogage n’est jamais exécutée, sh doit simplement passer au-dessus du noop (les variables et les caractères génériques sont développés). Si un débogage plus approfondi est requis, supprimez le noop de la variable et la fonction debug est appelée avec tous les arguments requis.
Une autre utilisation pratique est celle de commentaire de bloc, élément manquant dans la syntaxe du shell.
la source