Assegnare valori predefiniti alle variabili della shell con un singolo comando in bash


690

Ho un sacco di test sulle variabili in uno script di shell bash (3.00) in cui se la variabile non è impostata, assegna un valore predefinito, ad esempio:

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

Mi sembra di ricordare che esiste una sintassi per farlo in una riga, qualcosa che ricorda un operatore ternario, ad esempio:

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

(anche se so che non funzionerà ...)

Sono pazzo o esiste qualcosa del genere?


1
Shell Parameter La sezione di espansione del riferimento della shell bash è un buon punto di partenza: tiswww.case.edu/php/chet/bash/bashref.html#Shell-Expansions .
Kemin Zhou,

1
Documentazione di Gnu.org per Shell Parameter Expansion (suggerimento: ci sono molte altre cose interessanti che puoi fare!)
JDB ricorda ancora Monica il

Risposte:


1232

Molto vicino a quello che hai pubblicato, in realtà:

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

Oppure, che assegnerà defaulta VARIABLEcosì:

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

64
Se volessi trovarlo nella documentazione, cosa farebbe Google? Cercare su Google con caratteri speciali come $ {: -} non è molto semplice.
Joshua Olson,

20
In risposta al solarmista: "default assegnazione variabile bash" fammi entrare in questa pagina, e la ricerca nella pagina del manuale di bash con "variabile ass" mi
portò

57
Si noti che si tratta di non bash-specifici e lavorerà con tutta la shell-famiglia. È sicuro per script generici.
Jocelyn delalande,

16
@solarmist La parola chiave è "espansione dei parametri bash", se vuoi saperne di più su di esso e sui suoi compagni.
duleshi,

20
Ecco una spiegazione più approfondita sull'argomento unix.stackexchange.com/a/122848/2407
jottr

290

Per gli argomenti della riga di comando:

VARIABLE=${1:-DEFAULTVALUE}    

che assegna al VARIABLEvalore del 1 ° argomento passato allo script o al valore di DEFAULTVALUEse tale argomento non è stato passato.


245

Se la variabile è uguale, allora

: "${VARIABLE:=DEFAULT_VALUE}"

assegna DEFAULT_VALUE a VARIABLE se non definito. Le doppie virgolette evitano il globbing e la divisione delle parole.

Vedi anche la Sezione 3.5.3, Espansione dei parametri della shell , nel manuale di Bash.


27
Questo trucco complicato non era ovvio per me, usando il built-in: nessun effetto per mangiare l'espansione del $ {..} MA lasciando il set VARIABILE. Fino ad ora stavo facendo questo: VARIABLE = "$ {VARIABLE: -DEFAULT_VALUE}" e mi sentivo stanco di usare VARIABLE due volte.
dino,

Si scopre che NON FUNZIONA SEMPRE PER VARIABILI BASH-BUILTIN. È molto molto strano. Attualmente quelli a me noti sonoHISTTIMEFORMAT
Otheus,

come impostare più valori predefiniti? Ho provato ": $ {VARIABLE: = DEFAULT_VALUE}: $ {VARIABLE2: = DEFAULT_VALUE2}" ma sembra che non funzioni ...
Hans

8
@Hans: i due punti sono il comando (che non fa nulla) e quindi è necessario solo una volta. Ad esempio: ${FOO:=DEFAULT1} ${BAR:=DEFAULT2}
Patrik,

36

Anche tu puoi usare come valore predefinito il valore di un'altra variabile

avere un file defvalue.sh

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

echo $variable1
echo $variable2

eseguire l' ./defvalue.sh first-value second-valueoutput

first-value
second-value

ed esegui l' ./defvalue.sh first-valueoutput

first-value
first-value

28

vedi qui sotto 3.5.3 (espansione dei parametri della shell)

così nel tuo caso

${VARIABLE:-default}

26

Per rispondere alla tua domanda e su tutte le sostituzioni variabili

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, è possibile fornire un messaggio di errore in questo modo:

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

Questo visualizza un messaggio come questo ed esce con il codice 1:

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

Un esempio più completo di tutto:

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

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

Produzione:

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

$ export HOMEDIR=/home/myuser
$ ./script.sh foo
foo
/path/to/pwd
/home/myuser
  • $ACTION accetta il valore del primo argomento ed esce se vuoto
  • $DIRNAME è il secondo argomento e viene impostato automaticamente sulla directory corrente
  • $OUTPUT_DIRè il 3 ° argomento, o $HOMEDIR(se definito), altrimenti, /tmp. Funziona su OS X, ma non sono sicuro che sia portatile.

17

Quindi c'è il modo di esprimere il tuo costrutto "if" in modo più diretto:

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

10

Ecco un esempio

#!/bin/bash

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

echo "value: [$value]"

salvalo come script.sh e rendilo eseguibile. eseguirlo senza parametri

./script.sh
> value: [default_value]

eseguilo con param

./script.sh my_value
> value: [my_value]
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.