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?

Edward Q. Bridges
la source
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.
Andrew McGregor
la source
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é.

miku
la source
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.

Hans Ginzel
la source
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
Montells
la source
28

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

donc dans ton cas

${VARIABLE:-default}
ghostdog74
la source
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."
Gourou
la source
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.
Curtis Mattoon
la source
17

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

FOO='default'
[ -n "${VARIABLE}" ] && FOO=${VARIABLE}
Rob Wells
la source
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]
Assaf Shomer
la source