Que signifie: $ {param: = valeur}?

34

J'ai lu ce qui suit dans le Guide de l'utilisateur du Z-Shell :

Un synonyme de 'true' est ':'; il est souvent utilisé sous cette forme pour donner des arguments qui ont des effets secondaires mais qui ne devraient pas être utilisés - quelque chose comme

: ${param:=value}

qui est un idiome commun dans tous les dérivés Bourne Shell. Dans le paramètre expansion, $paramest donnée la valeur valeur si elle était vide auparavant, et laissée seule sinon. Comme c'était la seule raison du développement du paramètre, vous utilisez :pour ignorer l'argument. En fait, le shell construit allègrement la ligne de commande - les deux points, suivis de la valeur de $paramis, que l'affectation ait eu lieu ou non - exécute ensuite la commande; il se trouve que ':' ne prend pas en compte les arguments qui lui ont été donnés.

mais je ne le comprends pas. Je reçois que des :moyens true, mais il y a deux dans l'expression côlons. Comme question mineure, pourquoi cet idiome est-il tellement utilisé dans tous les dérivés de Bourne Shell? A quoi est-ce que ça sert?

Note: Je suis intéressé par ce que cet idiome fait à la fois en bash et en zsh .

Merci

Amelio Vazquez-Reina
la source
Demandez-vous zshou bash?
enzotib
@enzotib, je suis intéressé par les deux. J'ai clarifié cela.
Amelio Vazquez-Reina Le

Réponses:

31

Brisons cela en morceaux.

Ce code exécute la commande :avec quelques arguments. La commande :ne fait rien et ignore ses arguments. Par conséquent, toute la ligne de commande ne fait rien, sauf les effets secondaires éventuels sur les arguments.

La syntaxe ${parameter_name:=value}existe dans tous les shells de style Bourne non anciens, y compris ash, bash, ksh et zsh. Il définit le paramètre sur une valeur par défaut si nécessaire. C'est équivalent à

if [ -z "$parameter_name" ]; then parameter_name=value; fi
 ${parameter_name}

En d'autres termes, si parameter_namen'est pas défini ou s'il est défini sur une valeur vide, définissez-le sur la valeur indiquée; puis exécutez la commande en utilisant la nouvelle valeur du paramètre. Il existe une variante, ${parameter_name=value}qui laisse le paramètre vide s'il était vide, n'utilisant la valeur indiquée que si le paramètre était non défini.

Vous trouverez cette syntaxe documentée sous «Développement de paramètres» dans les spécifications POSIX et dans les manuels dash, bash, ksh et zsh.

Il existe des variantes de cette syntaxe, notamment ${parameter_name:-value}qui vous permettent d'utiliser une valeur par défaut pour cette extension uniquement, sans affecter le paramètre.

En résumé, : ${parameter_name:=value}une écriture concise

if [ -z "$parameter_name" ]; then parameter_name=value; fi
Gilles, arrête de faire le mal
la source
11

:vous ne pensez probablement pas à vrai while :, mais même dans cette expression, cela ne signifie pas «vrai», cela se produit simplement à évaluer (en fait, il s’agit simplement d’une commande nulle ou noop).

Ce paramètre expansion ( ${x:=y}) signifie "attribuer y à x si x est non défini ou vide, et passer à y ".

$ echo "${foo:=bar}"
bar
$ foo=baz
$ echo "${foo:=bar}"
baz
$ foo=
$ echo "${foo:=bar}"
bar
$ echo "${foo}"
bar

Le wiki Bash Les pirates informatiques a un bon article sur l' expansion des paramètres ici .

La raison :utilisée est la suivante: alors que les autres parties de la commande sont évaluées, elles ne font l'objet d'aucune action (comme :c'est le cas d'une commande nulle). Ainsi, vous avez ${x:=y}rempli sa fonction sans affecter quoi que ce soit d'autre, par exemple, si vous ne l'aviez pas :au début, il essaierait d'exécuter une commande appelée y .

Voici bashla page d'aide de ::

:: :
    Null command.

    No effect; the command does nothing.

    Exit Status:
    Always succeeds.
Chris Down
la source
3

La première :est une commande, elle s'appelle "noop" ou "pas d'opération". Comme indiqué dans la page de manuel, il est souvent utilisé pour évaluer les arguments.

Le second :est un qualificatif dans l’extension de la variable - techniquement, c’est le cas :=. Comme indiqué, cela définit la valeur si elle n'a pas de valeur.

Idiom-sage, si vous avez besoin d'une valeur par défaut d'une variable d'environnement, vous pouvez utiliser cette syntaxe. Par exemple, lors de l'exécution d'un programme cron(8), l'environnement n'est pas défini et les fichiers de points du shell ne sont pas exécutés. Vous devrez donc peut-être définir des valeurs par défaut.

: ${JAVA_HOME:=/usr/local/jdk-1.6.0_28}

Ensuite, vous pouvez "le définir et l’oublier" (jusqu’à ce que le format par défaut soit modifié).

Arcege
la source