come verificare se $ 1 e $ 2 sono nulli?


41

Sto eseguendo alcuni script che passano l'argomento stringa e voglio fare se l'istruzione else mostrata di seguito:

if [ $1 != '' ] && [ $2 != '' ]
then 
    do something.....

ma ha mostrato Error too many argument. Perché?


Dovresti fornire 1. il comando che chiami lo script e 2. l'output completo.
Lucio,

2
Si dovrebbe usare [[ ]]. Altrimenti devi citare le tue variabili.
Christophe De Troyer

Se $ 1 non esistesse, allora $ 2 diventerebbe $ 1, il che rende il test di $ 1 e $ 2 entrambi nulli sembrano irrilevanti.
WinEunuuchs2Unix il

@ WinEunuuchs2Unix Non necessariamente irrilevante - in alcuni casi vuoi assicurarti che ci sia effettivamente qualcosa invece di una stringa vuota o nulla negli argomenti. $1potrebbe essere non impostato o impostato su stringa null dall'utente dello script. Considera questa sequenza di comandi: $ set '' barquindi echo "x${1}x";Entrambe le variabili sono impostate, ma una di esse è nulla.
Sergiy Kolodyazhnyy il

Risposte:


56

Prova a usare il test -z:

if [ -z "$1" ] && [ -z "$2" ]

Dall'uomo bash:

-z string
   True if the length of string is zero.

Per me funziona!
pengisgood,

è interessante che la risposta più votata e accettata non risponda effettivamente alla domanda posta.
Mehmet,

Quando si scrivono script di shell portatili, questo flag dovrebbe essere usato con cura, poiché su alcuni Unix commerciali questo flag è difettoso. Vedi la mia risposta per le fonti collegate.
Sergiy Kolodyazhnyy il

14

Poiché questo è taggato bash, ti consiglio di usare il costrutto di test esteso ( [[...]]) e dimenticare le virgolette:

if [[ -z $1 && -z $2 ]]; then
...

A meno che non si stia cercando la shcompatibilità / POSIX, non vi è alcun motivo per non utilizzarlo [[ ]].


3

Di seguito funziona anche,

if [ "$1" == "" && "$2" == ""]; then
    echo NULL
fi

I &&separatori di comandi logici e altri non sono consentiti nel classico test. Devi invece usare altri costrutti di test (tipo -a, credo)
muru,

3

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 bashnon sembra essere il caso:

$ [ $1 != '' ] && [ $2 != '' ]
bash: [: !=: unary operator expected

Con il /bin/shquale è effettivamente collegato a /bin/dashUbuntu, 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/teste perché sto usando bashe sh, allora dovresti sapere che [è alias per testcomando, che esiste anche come eseguibile autonomo o più comunemente - come shell integrata che è ciò che ciascuna shell utilizzerà per prima . Per quanto riguarda le ifdichiarazioni, 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 testcapisce. 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/shscript. Può anche essere combinato come in

if [ "x${var1}${var2}" == "x" ]; then
    ...
fi

Ovviamente potremmo usare la -zbandiera, tuttavia secondo la ricerca in alcune conchiglie, in particolare ksh88 (secondo Stephane Chazelas ), questa bandiera è difettosa.

Guarda anche


+1 per un approccio molto interessante.
WinEunuuchs2Unix

@ WinEunuuchs2Unix Modificato per renderlo ancora più interessante :)
Sergiy Kolodyazhnyy il

1

Penso che il titolo del post non sia accurato, poiché l'intenzione nel messaggio era di verificare se $ 1 e $ 2 non sono nulli. Nell'esempio dato mancavano solo doppie virgolette in $ 1 e $ 2 per funzionare. Le variabili devono essere racchiuse tra virgolette per essere espanse quando si confrontano le stringhe. Ma controllare se esistono $ 1 e $ 2 equivale a controllare se esistono $ 2, poiché non può esistere se $ 1 non esiste. Anche il comando 'if' non è necessario in questo caso, poiché 'test' restituisce true / false e usa '&&' come 'then' se return è 0 / true:

[ "$2" != '' ] && commands...

Più semplice, con -n (diverso da zero):

[ -n "$2" ] && commands...

Per "controllare se $ 1 e $ 2 sono nulli" sarebbe lo stesso di controllare se non ci sono parametri:

[ $# -eq 0 ] && commands...
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.