2012-10-26 11 views
97

Ho una profondità della variabile bash e vorrei testare se è uguale a 0. Nel caso si, voglio interrompere l'esecuzione dello script. Finora ho:bash scripting - controlla se la variabile bash è uguale a 0

zero=0; 

if [ $depth -eq $zero ]; then 
    echo "false"; 
    exit; 
fi 

Purtroppo, questo porta a:

[: -eq: unary operator expected 

(potrebbe essere un po 'impreciso a causa di traduzione)

prega, come posso modificare il mio script per ottenerlo lavoro?

risposta

88

Sembra che la variabile depth non sia impostata. Ciò significa che l'espressione [ $depth -eq $zero ] diventa [ -eq 0 ] dopo che bash sostituisce i valori delle variabili nell'espressione. Il problema qui è che l'operatore viene erroneamente utilizzato come operatore con un solo argomento (lo zero), ma richiede due argomenti. Questo è il motivo per cui viene visualizzato il messaggio di errore unario.

EDIT: Come Doktor J citato nel suo commento a questa risposta, un modo sicuro per evitare problemi con le variabili non impostate nei controlli è quello di racchiudere le variabili in "". Vedi il suo commento per la spiegazione.

if [ "$depth" -eq "0" ]; then 
    echo "false"; 
    exit; 
fi 

Una variabile non impostata utilizzato con il comando [ appare vuoto per colpire. È possibile verificare questo utilizzando le prove di sotto della quale tutti restituiscono true perché xyz è vuota o non impostato:

  • if [ -z ] ; then echo "true"; else echo "false"; fi
  • xyz=""; if [ -z "$xyz" ] ; then echo "true"; else echo "false"; fi
  • unset xyz; if [ -z "$xyz" ] ; then echo "true"; else echo "false"; fi
+1

sto ottenendo profondità come risultato da un altro programma. Ho provato a farlo eco e non c'era nulla nell'output. Tuttavia, quando uso [[]] come suggerito da @Jacek Dominiak, lo script funziona correttamente (ciò che è piuttosto strano se la variabile è davvero non impostata). Devo ammettere che non capisco cosa stia succedendo qui ... – Perlnika

+7

La tua variabile di profondità non è impostata. Ciò significa che bash vede un'espressione che dice '[-eq 0]; poi 'che non ha senso ad esso. '[[]]' è la versione più sicura che sembra rendere bash vederlo come [[null -eq 0]] che è corretto. – cyon

+3

Un modo più sicuro per controllare è racchiudere entrambi i lati tra virgolette doppie, ad esempio "if [" $ depth "-eq" 0 "]'; in questo modo, una variabile unset ('$ depth') valuta" "(che ovviamente non è uguale a zero) –

15

Prova:

zero=0; 

if [[ $depth -eq $zero ]]; then 
    echo "false"; 
    exit; 
fi 
+0

Ho lavorato, grazie !! A proposito, qual è il motivo del doppio [[ – Perlnika

+2

Le doppie parentesi sono più intelligenti nel preservare variabili non impostate/nulle come una parola separata nell'espressione. –

+0

@pavel, [è un built-in bash, vedi https://www.gnu.org/software/bash/manual/html_node/Bourne-Shell-Builtins.html#Bourne-Shell-Builtins –

41

Doppia parent esis ((...)) viene utilizzato per operazioni aritmetiche.

doppie parentesi quadre [[ ... ]] possono essere utilizzati per confrontare ed esaminare i numeri (solo numeri interi sono supportati), con i seguenti operatori:

· NUM1 -eq NUM2 returns true if NUM1 and NUM2 are numerically equal. 

· NUM1 -ne NUM2 returns true if NUM1 and NUM2 are not numerically equal. 

· NUM1 -gt NUM2 returns true if NUM1 is greater than NUM2. 

· NUM1 -ge NUM2 returns true if NUM1 is greater than or equal to NUM2. 

· NUM1 -lt NUM2 returns true if NUM1 is less than NUM2. 

· NUM1 -le NUM2 returns true if NUM1 is less than or equal to NUM2. 

Per esempio

if [[ $age > 21 ]] # bad, > is a string comparison operator 

if [ $age > 21 ] # bad, > is a redirection operator 

if [[ $age -gt 21 ]] # okay, but fails if $age is not numeric 

if (($age > 21)) # best, $ on age is optional 
+3

Puoi fornire qualche ragionamento/prova perché alcuni approcci sono buoni e altri cattivi? – Dennis

+0

@Dennis: [Questo] (http://tldp.org/LDP/abs/html/comparison-ops.html) sembra verificare le istruzioni nella risposta (-> le diverse parentesi per confronto tra stringhe e interi) – mozzbozz

+0

'meglio, $ on age è opzionale' Non funziona senza' $' –

2

Si può provare questo:

: ${depth?"Error Message"} ## when your depth variable is not even declared or is unset. 

NOTA: qui è solo ? dopo depth.

o

: ${depth:?"Error Message"} ## when your depth variable is declared but is null like: "depth=". 

NOTA: qui è :? dopo depth.

Qui se viene trovata la variabile null, verrà stampato il messaggio di errore e quindi verrà chiuso.

1

In particolare: ((depth)). Ad esempio, le seguenti stampe 1.

declare -i x=0 
((x)) && echo $x 

x=1 
((x)) && echo $x 
6

è anche possibile utilizzare questo formato e utilizzare gli operatori di confronto come '==' '< ='

if (($total == 0)); then 
     echo "No results for ${1}" 
     return 
    fi