Assigner des valeurs par défaut aux variables shell avec une seule commande dans bash


690

J'ai tout un tas de tests sur les variables dans un script shell bash (3.00) où si la variable n'est pas définie, elle attribue une valeur par défaut, par exemple:

if [ -z "${VARIABLE}" ]; then 
    FOO='default'
else 
    FOO=${VARIABLE}
fi

Je semble me rappeler qu'il y a une syntaxe pour faire cela en une seule ligne, quelque chose qui ressemble à un opérateur ternaire, par exemple:

FOO=${ ${VARIABLE} : 'default' }

(même si je sais que ça ne marchera pas ...)

Suis-je fou, ou existe-t-il quelque chose comme ça?


1
La section Expansion des paramètres du shell de la référence du shell bash est un bon point de départ: tiswww.case.edu/php/chet/bash/bashref.html#Shell-Expansions .
Kemin Zhou

1
Documentation Gnu.org pour Shell Parameter Expansion (indice: il y a beaucoup d'autres trucs sympas que vous pouvez faire!)
JDB se souvient encore de Monica le

Réponses:


1232

Très proche de ce que vous avez posté, en fait:

FOO=${VARIABLE:-default}  # If variable not set or null, use default.

Ou, qui assignera defaultà VARIABLEainsi:

FOO=${VARIABLE:=default}  # If variable not set or null, set it to default.

64
Si je voulais trouver cela dans la documentation, à quoi servirait un google? Googler avec des caractères spéciaux comme $ {: -} n'est pas très facile.
Joshua Olson

20
En réponse à solarmist: "bash variable assignation default" permettez-moi de cette page, et la recherche de la page de manuel de bash avec 'variable ass' m'a
conduit

57
Notez qu'il n'est pas spécifique à bash et fonctionnera avec toute la famille shell. C'est sûr pour les scripts génériques.
Jocelyn delalande

16
@solarmist Le mot clé est "expansion des paramètres bash", si vous voulez en savoir plus sur lui et ses compagnons.
duleshi

20
Voici une explication plus approfondie sur le sujet unix.stackexchange.com/a/122848/2407
jottr

290

Pour les arguments de ligne de commande:

VARIABLE=${1:-DEFAULTVALUE}    

qui assigne à VARIABLEla valeur du 1er argument passé au script ou à la valeur de DEFAULTVALUEsi aucun tel argument n'a été passé.


245

Si la variable est la même, alors

: "${VARIABLE:=DEFAULT_VALUE}"

affecte DEFAULT_VALUE à VARIABLE s'il n'est pas défini. Les guillemets doubles empêchent la globalisation et la division des mots.

Voir également la section 3.5.3, Expansion des paramètres du shell , dans le manuel de Bash.


27
Cette astuce n'était pas évidente pour moi, en utilisant le: aucun effet intégré pour manger l'expansion de $ {..} MAIS en laissant VARIABLE défini. Jusqu'à présent, je faisais ceci: VARIABLE = "$ {VARIABLE: -DEFAULT_VALUE}" et je me sentais idiot pour utiliser VARIABLE deux fois.
dino

Il s'avère que CECI NE FONCTIONNE PAS TOUJOURS POUR LES VARIABLES BASH-BUILTIN. C'est très très bizarre. Actuellement, ceux que je HISTTIMEFORMAT
connais

comment définir plusieurs valeurs par défaut? J'ai essayé ": $ {VARIABLE: = DEFAULT_VALUE}: $ {VARIABLE2: = DEFAULT_VALUE2}" mais cela ne semble pas fonctionner ...
Hans

8
@Hans: Le deux-points est la commande (qui ne fait rien) et n'est donc nécessaire qu'une seule fois. Par exemple: ${FOO:=DEFAULT1} ${BAR:=DEFAULT2}
Patrik

36

Même vous pouvez utiliser comme valeur par défaut la valeur d'une autre variable

avoir un dossier defvalue.sh

#!/bin/bash
variable1=$1
variable2=${2:-$variable1}

echo $variable1
echo $variable2

exécuter la ./defvalue.sh first-value second-valuesortie

first-value
second-value

et exécuter la ./defvalue.sh first-valuesortie

first-value
first-value

28

voir ici sous 3.5.3 (expansion des paramètres du shell)

donc dans ton cas

${VARIABLE:-default}

26

Pour répondre à votre question et sur toutes les substitutions variables

echo "$\{var}"
echo "Substitute the value of var."


echo "$\{var:-word}"
echo "If var is null or unset, word is substituted for var. The value of var does not change."


echo "$\{var:=word}"
echo "If var is null or unset, var is set to the value of word."


echo "$\{var:?message}"
echo "If var is null or unset, message is printed to standard error. This checks that variables are set correctly."


echo "$\{var:+word}"
echo "If var is set, word is substituted for var. The value of var does not change."

18

FWIW, vous pouvez fournir un message d'erreur comme ceci:

USERNAME=${1:?"Specify a username"}

Cela affiche un message comme celui-ci et se termine avec le code 1:

./myscript.sh
./myscript.sh: line 2: 1: Specify a username

Un exemple plus complet de tout:

#!/bin/bash
ACTION=${1:?"Specify 'action' as argv[1]"}
DIRNAME=${2:-$PWD}
OUTPUT_DIR=${3:-${HOMEDIR:-"/tmp"}}

echo "$ACTION"
echo "$DIRNAME"
echo "$OUTPUT_DIR"

Production:

$ ./script.sh foo
foo
/path/to/pwd
/tmp

$ export HOMEDIR=/home/myuser
$ ./script.sh foo
foo
/path/to/pwd
/home/myuser
  • $ACTION prend la valeur du premier argument et quitte s'il est vide
  • $DIRNAME est le 2ème argument, et revient par défaut au répertoire courant
  • $OUTPUT_DIRest le 3ème argument ou $HOMEDIR(si elle est définie), sinon, /tmp. Cela fonctionne sur OS X, mais je ne suis pas certain que ce soit portable.

17

Ensuite, il y a la façon d'exprimer plus laconiquement votre construction `` if '':

FOO='default'
[ -n "${VARIABLE}" ] && FOO=${VARIABLE}

10

Voici un exemple

#!/bin/bash

default='default_value'
value=${1:-$default}

echo "value: [$value]"

enregistrez-le sous script.sh et rendez-le exécutable. exécutez-le sans params

./script.sh
> value: [default_value]

exécutez-le avec param

./script.sh my_value
> value: [my_value]
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.