bash attribuer une valeur par défaut

135

$ {paramètre: = mot} Attribuer des valeurs par défaut. Si le paramètre est non défini ou nul, le développement du mot est affecté au paramètre. La valeur du paramètre est alors substituée. Les paramètres de position et les paramètres spéciaux ne peuvent pas être affectés de cette manière.

Je pensais que je pourrais utiliser cette fonctionnalité pour écrire ${LONG_VARIABLE_NAME:=hello}au lieu de la plus longue LONG_VARIABLE_NAME=${LONG_VARIABLE_NAME:-hello}, mais maintenant, bash essaie également d'exécuter «bonjour» et cela donne une commande introuvable. Un moyen d'éviter cela? Ou vais-je devoir m'en tenir à ce dernier? Quelqu'un peut-il donner un exemple où l'affectation par défaut est réellement utile?

zedoo
la source
13
Lorsque vous citez du texte, il est utile d'inclure un lien vers la source.
Jonathon Reinhart du

Réponses:

202

Utilisez deux points:

: ${A:=hello}

Le signe deux-points est une commande nulle qui ne fait rien et ignore ses arguments. Il est intégré à bash afin qu'aucun nouveau processus ne soit créé.

camh
la source
93
Je ne peux m'empêcher d'observer que : ${A:=hello}c'est exactement aussi long que A=${A:-hello}. Il semble aussi que ce dernier soit un peu moins ésotérique et que son intention soit plus claire. L'utilisation :, qui est essentiellement un no-op, semble dérisoire par rapport à la façon dont l'OP le faisait auparavant.
Dan Moulding
5
@camh: d'accord. Je peux voir où, si vous aviez beaucoup de variables à initialiser aux valeurs par défaut et qu'elles ont des noms longs, l' :approche serait préférable, à la fois pour la saisie et pour la lecture. Oui, cela semble être un domaine dans lequel Bash pourrait utiliser une petite amélioration.
Dan Molding
17
@DanMoulding: qu'en est-il de : ${VERY_LONG_VARIABLE_NAME:=hello}vs VERY_LONG_VARIABLE_NAME=${VERY_LONG_VARIABLE_NAME:-hello}. : . J'espère que vous utilisez des noms de variables descriptifs dans votre code :)
pihentagy
18
Non seulement plus court, mais moins sujette aux erreurs: VERY_LONG_VARIABLE_NAME=${VERY_LOGN_VARIABLE_NAME:-hello}. Oups.
chepner
5
Un avantage de l' A=$A:-helloapproche est qu'elle se documente automatiquement lorsqu'elle est exécutée avec set -x. Autrement dit, l'affectation s'imprimera comme A=helloalors que la commande null n'imprimerait que la valeur ( hello).
lmsurprenant le
107

Veuillez consulter http://www.tldp.org/LDP/abs/html/parameter-substitution.html pour des exemples

${parameter-default}, ${parameter:-default}

Si le paramètre n'est pas défini, utilisez la valeur par défaut. Après l'appel, le paramètre n'est toujours pas défini.
Les deux formes sont presque équivalentes. L'extra ne :fait une différence que lorsque le paramètre a été déclaré, mais est nul.

unset EGGS
echo 1 ${EGGS-spam}   # 1 spam
echo 2 ${EGGS:-spam}  # 2 spam

EGGS=
echo 3 ${EGGS-spam}   # 3
echo 4 ${EGGS:-spam}  # 4 spam

EGGS=cheese
echo 5 ${EGGS-spam}   # 5 cheese
echo 6 ${EGGS:-spam}  # 6 cheese

${parameter=default}, ${parameter:=default}

Si le paramètre n'est pas défini, définissez la valeur du paramètre sur la valeur par défaut.
Les deux formes presque équivalentes. Le: fait une différence uniquement lorsque le paramètre a été déclaré et est nul

# sets variable without needing to reassign
# colons suppress attempting to run the string
unset EGGS
: ${EGGS=spam}
echo 1 $EGGS     # 1 spam
unset EGGS
: ${EGGS:=spam}
echo 2 $EGGS     # 2 spam

EGGS=
: ${EGGS=spam}
echo 3 $EGGS     # 3        (set, but blank -> leaves alone)
EGGS=
: ${EGGS:=spam}
echo 4 $EGGS     # 4 spam

EGGS=cheese
: ${EGGS:=spam}
echo 5 $EGGS     # 5 cheese
EGGS=cheese
: ${EGGS=spam}
echo 6 $EGGS     # 6 cheese

${parameter+alt_value}, ${parameter:+alt_value}

Si le paramètre est défini, utilisez alt_value, sinon utilisez une chaîne nulle. Après l'appel, la valeur du paramètre n'a pas été modifiée.
Les deux formes presque équivalentes. Le: fait une différence uniquement lorsque le paramètre a été déclaré et est nul

unset EGGS
echo 1 ${EGGS+spam}  # 1
echo 2 ${EGGS:+spam} # 2

EGGS=
echo 3 ${EGGS+spam}  # 3 spam
echo 4 ${EGGS:+spam} # 4

EGGS=cheese
echo 5 ${EGGS+spam}  # 5 spam
echo 6 ${EGGS:+spam} # 6 spam
Jonathan L
la source
20

L'expansion des paramètres de valeur par défaut est souvent utile dans les scripts de construction comme l'exemple ci-dessous. Si l'utilisateur appelle simplement le script tel quel, perl ne sera pas intégré. L'utilisateur doit définir explicitement WITH_PERLune valeur autre que "no" pour l'avoir intégré.

$ cat defvar.sh
#!/bin/bash

WITH_PERL=${WITH_PERL:-no}

if [[ "$WITH_PERL" != no ]]; then
    echo "building with perl"
    # ./configure --enable=perl
else
    echo "not building with perl"
    # ./configure
fi

Construire sans Perl

$ ./defvar.sh
not building with perl

Construire avec Perl

$ WITH_PERL=yes ./defvar.sh
building with perl
SiegeX
la source