Per la vecchia versione della risposta, vedere la seconda parte di questa risposta. Se vuoi conoscere i dettagli, continua a leggere
La causa del problema
Nella domanda stessa, è stato riferito che OP vede too many arguments error
, che quando testato in bash
non sembra essere il caso:
$ [ $1 != '' ] && [ $2 != '' ]
bash: [: !=: unary operator expected
Con il /bin/sh
quale è effettivamente collegato a /bin/dash
Ubuntu, l'errore segnalato come segue:
$ sh
$ [ $1 != '' ] && [ $2 != '' ]
sh: 1: [: !=: unexpected operator
E anche il standalone /bin/test
:
$ /usr/bin/test $1 != ''
/usr/bin/test: missing argument after ‘’
Sidenote: se ti stai chiedendo cosa sia /usr/bin/test
e perché sto usando bash
e sh
, allora dovresti sapere che [
è alias per test
comando, che esiste anche come eseguibile autonomo o più comunemente - come shell integrata che è ciò che ciascuna shell utilizzerà per prima . Per quanto riguarda le if
dichiarazioni, operano su statue di comandi di uscita, quindi perché [
etest
sono comandi, con tutto il resto che sono argomenti a quei comandi - l'ordine improprio di questi argomenti della riga di comando porta ad errori.
Torna all'argomento: non è chiaro come OP abbia ottenuto l'errore non correlato. Tuttavia, in tutti e 3 i casi il problema è lo stesso: la variabile non impostata verrà trattata come vuota, quindi ciò che la shell vede con queste variabili non quotate è
[ != '' ]
che rompe la sintassi che test
capisce. Ricordi cosa ho detto sull'ordine improprio degli argomenti della riga di comando? Ecco perché la citazione è importante. Abilitiamo l'output diagnostico e vediamo cosa esegue la shell:
$ set -x
# throws error
$ [ $1 != '' ] && [ $2 != '' ]
+ '[' '!=' '' ']'
bash: [: !=: unary operator expected
# no error
$ [ "$1" != '' ] && [ "$2" != '' ] || echo null vars
+ '[' '' '!=' '' ']'
+ echo null vars
null vars
Modo migliore per testare le variabili non impostate
Un approccio molto frequente che vedi in giro è questo:
if [ "x$var1" == "x" ] && [ "x$var2" == "x" ];
then
echo "both variables are null"
fi
Per citare Gilles :
In ["x $ 1" = "x"], il prefisso x assicura che x "$ 1" non possa apparire come un operatore, quindi l'unico modo in cui la shell può analizzare questo test è trattando = come un operatore binario.
Presumibilmente, questo dovrebbe essere abbastanza portatile dal momento che ho visto questi negli /bin/sh
script. Può anche essere combinato come in
if [ "x${var1}${var2}" == "x" ]; then
...
fi
Ovviamente potremmo usare la -z
bandiera, tuttavia secondo la ricerca in alcune conchiglie, in particolare ksh88 (secondo Stephane Chazelas ), questa bandiera è difettosa.
Guarda anche