2012-10-26 18 views
97

Ich habe eine Bash variable Tiefe und ich möchte testen, ob es gleich 0 ist. Im Falle ja, ich möchte die Ausführung des Skripts stoppen. Bisher habe ich:Bash Scripting - Überprüfen Sie, ob die Bash-Variable 0 ist

zero=0; 

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

Leider führt dies zu:

[: -eq: unary operator expected 

(vielleicht ein bisschen ungenau aufgrund Übersetzung)

Bitte, wie kann ich mein Skript ändern, um es zu bekommen Arbeiten?

Antwort

88

Sieht so aus, als ob Ihre depth Variable nicht gesetzt ist. Dies bedeutet, dass der Ausdruck [ $depth -eq $zero ] zu [ -eq 0 ] wird, nachdem bash die Werte der Variablen in den Ausdruck ersetzt. Das Problem hierbei ist, dass der Operator -eq fälschlicherweise als Operator mit nur einem Argument (der Null) verwendet wird, jedoch zwei Argumente benötigt. Deshalb erhalten Sie den unären Operator Fehlermeldung.

EDIT: Als Doktor J in seinem Kommentar zu dieser Antwort erwähnt, ist eine sichere Möglichkeit, Probleme mit nicht definierter Variablen in Kontrollen zu vermeiden, ist die Variablen in "" einzuschließen. Siehe seinen Kommentar für die Erklärung.

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

Eine ungesetzt Variable mit dem [ Befehl erscheint leer einzuschlagen. Sie können dies mit Hilfe der folgenden Tests überprüfen, die sich alle auf true bewerten, weil xyz entweder leer oder nicht gesetzt ist:

  • 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

Ich erhalte Tiefe als Ergebnis von einem anderen Programm verwendet werden. Ich habe versucht, es zu wiederholen und es gab nichts in der Ausgabe. Wenn ich jedoch [[]] als @Jacek Dominiak vorgeschlagen habe, funktioniert das Skript korrekt (was ziemlich merkwürdig ist, wenn die Variable wirklich nicht gesetzt ist). Ich muss zugeben, dass ich nicht wirklich verstehe, was hier passiert ... – Perlnika

+7

Ihre Tiefenvariable ist nicht gesetzt. Das bedeutet, bash sieht einen Ausdruck, der besagt: [-eq 0]; dann ", was keinen Sinn ergibt. '[[]]' ist die sicherere Version, die bash anscheinend als [[null -eq 0]] erscheinen lässt, was korrekt ist. – cyon

+3

Ein sicherer Weg zu überprüfen ist, beide Seiten in Anführungszeichen zu setzen, d. H. 'If [" $ depth "-eq" 0 "]'; Auf diese Weise wird eine nicht gesetzte Variable ('$ depth') zu" "ausgewertet (was natürlich nicht gleich Null ist) –

15

Versuchen:

zero=0; 

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

Ich arbeitete, danke !! Btw, was der Grund für double [[ – Perlnika

+2

] Die doppelten Klammern sind klüger über das Beibehalten von Unset/Null Variablen als ein separates Wort im Ausdruck. –

+0

@pavel, [ist eine integrierte Bash, siehe https://www.gnu.org/software/bash/manual/html_node/Bourne-Shell-Builtins.html#Bourne-Shell-Builtins –

41

Doppelzimmer Eltern esis ((...)) wird für arithmetische Operationen verwendet.

Doppel eckige Klammern [[ ... ]] verwendet werden kann, um Zahlen zu vergleichen und prüfen (nur ganze Zahlen werden unterstützt), mit den folgenden Operatoren:

· 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. 

Zum Beispiel

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

Können Sie einige Argumentation bieten/Beweise, warum einige Ansätze gut und andere schlecht sind? – Dennis

+0

@Dennis: [This] (http://tldp.org/LDP/abs/html/comparison-ops.html) scheint die Aussagen in der Antwort zu überprüfen (-> die verschiedenen Klammern für String vs. Integer-Vergleich) – mozzbozz

+0

'best, $ on age ist optional' Es funktioniert nicht ohne' $ ' –

2

Sie können dies versuchen:

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

HINWEIS: Hier ist es nur ? nach depth.

oder

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

HINWEIS: Hier ist es :? nach depth.Wenn die Variable depthnull gefunden wird, wird die Fehlermeldung ausgegeben und dann beendet.

1

Spezifisch: ((depth)). Das folgende Beispiel druckt 1.

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

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

Sie können dieses Format verwenden und Vergleichsoperatoren wie ‚==‘ ‚< =‘

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