Risposte:
#!/bin/bash
set -o nounset
VALUE=${WHATEVER:-}
if [ ! -z ${VALUE} ];
then echo "yo"
fi
echo "whatever"
In questo caso, VALUE
finisce per essere una stringa vuota se WHATEVER
non è impostata. Stiamo usando l' {parameter:-word}
espansione, che puoi cercare in man bash
"Parameter Expansion".
:-
controlla se la variabile non è impostata o è vuota. Se si desidera controllare solo se è impostata, utilizzare -
: VALUE=${WHATEVER-}
. Inoltre, un modo più leggibile per verificare se una variabile è vuota:if [ "${WHATEVER+defined}" = defined ]; then echo defined; else echo undefined; fi
$WHATEVER
contiene solo spazi bianchi - Vedi la mia risposta.
! -z
" invece di " -n
"?
Devi citare le variabili se vuoi ottenere il risultato che ti aspetti:
check() {
if [ -n "${WHATEVER-}" ]
then
echo 'not empty'
elif [ "${WHATEVER+defined}" = defined ]
then
echo 'empty but defined'
else
echo 'unset'
fi
}
Test:
$ unset WHATEVER
$ check
unset
$ WHATEVER=
$ check
empty but defined
$ WHATEVER=' '
$ check
not empty
"info bash"
, "${WHATEVER-}"
dovrebbe avere un ":"
(due punti) prima della "-"
(trattino) come: "${WHATEVER:-}"
e "${WHATEVER+defined}"
dovrebbe avere due punti prima che il "+"
(più) come: "${WHATEVER:+defined}"
. Per me, funziona in entrambi i casi, con o senza il colon. Su alcune versioni di 'nix probabilmente non funzionerà senza includere i due punti, quindi probabilmente dovrebbe essere aggiunto.
-
, +
, :+
, e :-
sono tutti supportati. Il primo rileva se la variabile è impostata e il secondo rileva se è impostata o vuota . Da man bash
: "Omettendo i due punti si ottiene un test solo per un parametro non impostato".
Che ne dici di un oneliner?
[ -z "${VAR:-}" ] && echo "VAR is not set or is empty" || echo "VAR is set to $VAR"
-z
controlla sia la variabile vuota che non impostata
-z
controlla solo se il parametro successivo è vuoto. -z
è solo un argomento del [
comando. L'espansione variabile avviene prima che [ -z
possa fare qualsiasi cosa.
Presupposti:
$ echo $SHELL
/bin/bash
$ /bin/bash --version | head -1
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
$ set -o nounset
Se si desidera che uno script non interattivo stampi un errore ed esca se una variabile è nulla o non è impostata:
$ [[ "${HOME:?}" ]]
$ [[ "${IAMUNBOUND:?}" ]]
bash: IAMUNBOUND: parameter null or not set
$ IAMNULL=""
$ [[ "${IAMNULL:?}" ]]
bash: IAMNULL: parameter null or not set
Se non vuoi che lo script esca:
$ [[ "${HOME:-}" ]] || echo "Parameter null or not set."
$ [[ "${IAMUNBOUND:-}" ]] || echo "Parameter null or not set."
Parameter null or not set.
$ IAMNULL=""
$ [[ "${IAMUNNULL:-}" ]] || echo "Parameter null or not set."
Parameter null or not set.
Puoi anche usare [
e ]
invece di [[
e ]]
sopra, ma quest'ultimo è preferibile in Bash.
Nota cosa fa il colon sopra. Dai documenti :
In altre parole, se vengono inclusi i due punti, l'operatore verifica l'esistenza di entrambi i parametri e che il suo valore non sia nullo; se i due punti vengono omessi, l'operatore verifica solo l'esistenza.
Apparentemente non c'è bisogno di -n
o -z
.
In sintesi, in genere posso solo usare [[ "${VAR:?}" ]]
. Per gli esempi, questo stampa un errore ed esce se una variabile è nulla o non è impostata.
Puoi usare
if [[ ${WHATEVER:+$WHATEVER} ]]; then
ma
if [[ "${WHATEVER:+isset}" == "isset" ]]; then
potrebbe essere più leggibile.
=
operatore standard (POSIX) , non ==
per facilitare la portabilità e [
invece di, [[
se possibile.
set -o nounset
quale è specifica per bash. Se metti un #!/bin/bash
all'inizio del tuo script, in realtà è meglio usare i miglioramenti di bash.
Anche se questo non è esattamente il caso d'uso richiesto sopra, ho scoperto che se vuoi usare nounset
(o -u
) il comportamento predefinito è quello che desideri: uscire da diverso da zero con un messaggio descrittivo.
Mi ci è voluto abbastanza tempo per rendermene conto che ho pensato che valesse la pena pubblicare come soluzione.
Se tutto ciò che vuoi è fare eco a qualcos'altro quando esci o fare un po 'di pulizia, puoi usare una trappola.
L' :-
operatore è probabilmente quello che vuoi altrimenti.