Se la tua $VARIABLE
è una stringa contenente spazi o altri caratteri speciali e vengono utilizzate parentesi quadre singole (che è una scorciatoia per il test
comando), la stringa può essere suddivisa in più parole. Ognuno di questi è trattato come un argomento separato.
In modo che una variabile sia suddivisa in molti argomenti :
VARIABLE=$(/some/command);
# returns "hello world"
if [ $VARIABLE == 0 ]; then
# fails as if you wrote:
# if [ hello world == 0 ]
fi
Lo stesso vale per qualsiasi chiamata di funzione che inserisce una stringa contenente spazi o altri caratteri speciali.
Soluzione semplice
Avvolgere l'output della variabile tra virgolette doppie, costringendolo a rimanere come una stringa (quindi un argomento). Per esempio,
VARIABLE=$(/some/command);
if [ "$VARIABLE" == 0 ]; then
# some action
fi
Semplice come quella. Passa a "Attenzione anche ..." di seguito se non puoi anche garantire che la tua variabile non sarà una stringa vuota o una stringa che non contiene altro che spazi bianchi.
In alternativa, una correzione alternativa consiste nell'utilizzare parentesi quadre doppie (che è una scorciatoia per il new test
comando).
Questo esiste solo in bash (e apparentemente korn e zsh) tuttavia, e quindi potrebbe non essere compatibile con le shell predefinite chiamate da /bin/sh
ecc.
Ciò significa che su alcuni sistemi, potrebbe funzionare dalla console ma non quando viene chiamato altrove, come dacron
, a seconda di come tutto è configurato.
Sarebbe così:
VARIABLE=$(/some/command);
if [[ $VARIABLE == 0 ]]; then
# some action
fi
Se il tuo comando contiene parentesi quadre doppie come questa e ottieni errori nei log ma funziona dalla console, prova a scambiare la [[
con un'alternativa qui suggerita, oppure assicurati che qualunque cosa esegua il tuo script utilizza una shell che supporta [[
aka new test
.
Attenzione anche [: unary operator expected
all'errore
Se visualizzi l'errore "troppi argomenti", è probabile che stai ricevendo una stringa da una funzione con output imprevedibile. Se è anche possibile ottenere una stringa vuota (o tutta la stringa degli spazi bianchi), questa verrebbe trattata come argomento zero anche con la "soluzione rapida" precedente e fallirebbe con[: unary operator expected
È lo stesso 'gotcha' se sei abituato ad altre lingue - non ti aspetti che il contenuto di una variabile venga effettivamente stampato nel codice in questo modo prima che venga valutato.
Ecco un esempio che impedisce sia la [: too many arguments
e gli [: unary operator expected
errori: sostituendo l'uscita con un valore predefinito se vuoto (in questo esempio, 0
), con virgolette avvolto intorno il tutto:
VARIABLE=$(/some/command);
if [ "${VARIABLE:-0}" == 0 ]; then
# some action
fi
(qui l'azione si verificherà se $ VARIABLE è 0 o vuoto. Naturalmente, è necessario modificare lo 0 (valore predefinito) in un valore predefinito diverso se si desidera un comportamento diverso)
Nota finale: poiché [
è una scorciatoia per test
, tutto quanto sopra vale anche per l'errore test: too many arguments
(e anche test: unary operator expected
)