bash assegna un valore predefinito


135

$ {parametro: = parola} Assegna valori predefiniti. Se il parametro non è impostato o è nullo, l'espansione della parola viene assegnata al parametro. Il valore del parametro viene quindi sostituito. In questo modo non è possibile assegnare parametri posizionali e parametri speciali.

Pensavo di poter usare questa funzione per scrivere ${LONG_VARIABLE_NAME:=hello}invece che più a lungo LONG_VARIABLE_NAME=${LONG_VARIABLE_NAME:-hello}, ma ora bash tenta anche di eseguire 'ciao' e questo dà un comando non trovato. Un modo per evitarlo? O dovrò attenermi a quest'ultimo? Qualcuno può fare un esempio in cui l'assegnazione predefinita è effettivamente utile?


13
Quando si cita il testo è utile includere un collegamento alla fonte.
Jonathon Reinhart,

Risposte:


202

Usa i due punti:

: ${A:=hello}

I due punti sono un comando null che non fa nulla e ignora i suoi argomenti. È integrato in bash, quindi non viene creato un nuovo processo.


93
Non posso fare a meno di osservare che : ${A:=hello}è esattamente fino a quando A=${A:-hello}. Sembra anche che quest'ultimo sia un po 'meno esoterico e il suo intento sia più chiaro. L'uso :, che è fondamentalmente no-op, sembra complicato rispetto al modo in cui l'OP lo stava facendo prima.
Dan Molding,

5
@camh: concordato. Posso vedere dove, se avessi molte variabili da inizializzare ai valori di default e avessero nomi lunghi, l' :approccio sarebbe preferibile, sia per la digitazione che per la lettura. Sì, questa sembra un'area in cui Bash potrebbe usare un piccolo miglioramento.
Dan Molding,

17
@DanMoulding: che dire : ${VERY_LONG_VARIABLE_NAME:=hello}vs VERY_LONG_VARIABLE_NAME=${VERY_LONG_VARIABLE_NAME:-hello}. : . Spero che tu usi nomi di variabili descrittivi nel tuo codice :)
pihentagy,

18
Non solo più breve, ma meno soggetto a errori: VERY_LONG_VARIABLE_NAME=${VERY_LOGN_VARIABLE_NAME:-hello}. Ops.
Chepner,

5
Un vantaggio A=$A:-hellodell'approccio è che si documenta da sé quando viene eseguito set -x. Cioè, l'assegnazione verrà stampata come A=hellomentre il comando null stamperebbe solo il valore ( hello).
lmsurprenant,

107

Si prega di guardare http://www.tldp.org/LDP/abs/html/parameter-substitution.html per esempi

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

Se il parametro non è impostato, utilizzare l'impostazione predefinita. Dopo la chiamata, il parametro non è ancora impostato.
Entrambe le forme sono quasi equivalenti. Il supplemento :fa la differenza solo quando il parametro è stato dichiarato, ma è nullo.

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}

Se il parametro non è impostato, impostare il valore del parametro sul valore predefinito.
Entrambe le forme quasi equivalenti. : Fa la differenza solo quando il parametro è stato dichiarato ed è nullo

# 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}

Se il parametro è impostato, usa alt_value, altrimenti usa la stringa null. Dopo la chiamata, il valore del parametro non è cambiato.
Entrambe le forme quasi equivalenti. : Fa la differenza solo quando il parametro è stato dichiarato ed è nullo

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

20

L'espansione del parametro del valore predefinito è spesso utile negli script di compilazione come nell'esempio seguente. Se l'utente chiama semplicemente lo script così com'è, perl non verrà incorporato. L'utente deve impostare esplicitamente WITH_PERLun valore diverso da "no" per averlo incorporato.

$ 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

Costruisci senza Perl

$ ./defvar.sh
not building with perl

Costruisci con Perl

$ WITH_PERL=yes ./defvar.sh
building with perl
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.