Risposte:
#!/bin/bash
set -o nounset
VALUE=${WHATEVER:-}
if [ ! -z ${VALUE} ];
then echo "yo"
fi
echo "whatever"
In questo caso, VALUEfinisce per essere una stringa vuota se WHATEVERnon è 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
$WHATEVERcontiene 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
-zcontrolla solo se il parametro successivo è vuoto. -zè solo un argomento del [comando. L'espansione variabile avviene prima che [ -zpossa 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 -no -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 nounsetquale è specifica per bash. Se metti un #!/bin/bashall'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.