web-dev-qa-db-fra.com

Quel est le point de l'opérateur bash Null ":", deux points?

Quel est l'intérêt de l'opérateur "null" dans un script BASH? Je comprends qu’il est utilisé comme espace réservé après une commande if quand vous n’avez rien à dire, mais vous avez besoin d’une commande pour permettre au programme de s’exécuter correctement. Mais à quoi sert-il globalement? Quand l'utiliseriez-vous? Quand est-il judicieux de l'utiliser?

13
Justin

Il est parfois utile de permettre aux effets secondaires d'expansion des paramètres de se produire.

Par exemple, définir une valeur par défaut

read -p "Enter your name: " name
: ${name:=John Doe}  # if the user entered an empty string
echo "$name"
16
glenn jackman

Vous pouvez également l'utiliser pour des boucles sans fin:

while : ; do 
   # ....
done
13
choroba

Vous pouvez l’utiliser pour créer un fichier sans exécuter de programme:

: > /path/to/file

Ceci est infiniment plus rapide que touch /path/to/file (car il ne nécessite pas l'exécution du programme touch) et peut être légèrement plus portable que simplement

> /path/to/file

qui semble fonctionner sur de nombreux systèmes. De même, il peut être utilisé pour vérifier si vous avez un accès en écriture à un fichier :

if { : >> /path/to/file;} 2> /dev/null
then
    echo "writeable"
else
    echo "write permission denied"
fi

bien que cela puisse aussi être fait sans le :. Mises en garde:

  • Cela ne vérifie pas si le fichier existe déjà. Si ce n'est pas le cas, le fichier sera créé s'il est autorisé à le faire.
  • Si le fichier n’existe pas et que votre script n’est pas autorisé à le créer, le message "autorisation d’écriture refusée" sera indiqué.

(Voir la question liée pour les raisons pour lesquelles c'est plus fiable que if [ -w /path/to/file ].)

9
G-Man

Il y a bien longtemps, sous Unix V6 et Thompson Shell, le : était en fait utilisé dans le cadre de l'instruction goto. Selon le manuel , il est apparu à l'origine dans la version 3 d'Unix:

Le fichier de commande complet est recherché pour une ligne commençant par: en tant que premier caractère non vide, suivi par un ou plusieurs espaces, puis par le libellé. Si une telle ligne est trouvée, goto repositionne le décalage du fichier de commandes sur la ligne après le libellé et se termine. Cela provoque le transfert du shell sur la ligne étiquetée.

De nos jours, dans bash, il est utilisé en tant qu’opérateur non-op, ce qui donne un succès. En effet, si vous regardez le code source , vous verrez que true et : utilisent la même fonction, int colon_builtin(), en dessous. Il n'y a pas de commande : non intégrée, et /bin/true est en réalité une assez grande commande pour ce qu'elle fait.

: pourrait être utilisé n'importe où true est utilisé, par exemple dans command_that_can_fail || true, bien que cela risque de semer la confusion chez les non-experts. En savoir plus à ce sujet ici .

5

Vous pouvez l'utiliser sur le test positif d'une commande if lorsque vous souhaitez uniquement effectuer une opération du côté négatif. Par exemple:

if [[ True == False ]]; then
    :
else
    echo "true <> flase"
fi

Sans :, bash générerait une erreur de syntaxe.

Ceci est un exemple trop simpliste. Généralement, vous utiliseriez une telle technique dans le codage préliminaire lorsque vous n'avez pas encore écrit ce segment de code et que vous avez simplement besoin de quelque chose qui ne génère pas d'erreur.

3
WinEunuuchs2Unix

Je viens de l'utiliser dans un script avec des commandes SSH pour empêcher le script de se tromper.

Dans ce cas, je veux voir si un utilisateur peut se connecter à un ensemble de serveurs. Si la connexion est correcte, l'hôte distant affichera OK. Si la connexion échoue, SSH répondra avec l'erreur. Cependant, je souhaite que mon script se termine avec 0 et non la valeur de la commande SSH en cas d'échec. Donc, en gros, je piège l’erreur SSH en lui ordonnant || avec la commande null :. Ressemble à ça:

#!/bin/bash
for i in $(cat servers.txt); do
    echo -n "$i "; 
    ssh user@${i} 'echo OK' || :; 
done

De cette façon, je reçois la sortie de SSH mais pas le code d'erreur:

....
swl06 ok
swl07 ok
swl08 Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
swl09 ok
swl10 Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).
....
0
Michael J