Gegeben sei:
LEFT="yes" RIGHT=""
if [ $LEFT = "yes" ] && [ -z $RIGHT ]; then ...
allerdings wirft das den Fehler:
-bash: [: =: Einstelliger (unärer) Operator erwartet.
Was habe ich nicht verstanden?
Mit freundlichen Grüßen / Kind regards Ronny Seffner
2012-01-18 18:42, Ronny Seffner skrev:
Gegeben sei:
LEFT="yes" RIGHT=""
if [ $LEFT = "yes" ]&& [ -z $RIGHT ]; then ...
$ LEFT="yes" $ RIGHT="" $ if [ $LEFT = "yes" ]&& [ -z $RIGHT ]; then echo hi; fi hi $ bash --version GNU bash, version 4.2.10(1)-release (x86_64-pc-linux-gnu)
-bash: [: =: Einstelliger (unärer) Operator erwartet.
Das sagt er eigentlich, wenn $LEFT nicht gesetzt ist:
$ if [ $XLEFT = "yes" ]; then echo hi; fi bash: [: =: unary operator expected
Viele Grüße Fabian
Hi Ronny,
On Wed, Jan 18, 2012 at 18:42:53 +0100, Ronny Seffner wrote:
LEFT="yes" RIGHT=""
if [ $LEFT = "yes" ] && [ -z $RIGHT ]; then ...
allerdings wirft das den Fehler:
-bash: [: =: Einstelliger (unärer) Operator erwartet.
Was habe ich nicht verstanden?
Du solltest in beiden Tests die Variablenexpansion quoten, damit dort jeweils ein Argument rauskommt. Also: if [ "$LEFT" = "yes" ] && [ -z "$RIGHT" ]; ...
Sonst bekommst Du folgende Probleme:
1.
LEFT="" if [ $LEFT = "yes" ] && [ -z $RIGHT ]; ...
[: =: unary operator expected
Hier expandiert $LEFT zu _nichts_, also noch nicht mal zu einem leeren Argument. Deshalb beschwert sich das test-Kommando ([), dass bei einer Folge von Operator (=) und Operand ("yes") der Operator ein unaerer sein muss. Der Gleichheitsoperator ist aber ein binaerer (will zwei Argumente).
2.
LEFT="yes sir" if [ $LEFT = "yes" ] && [ -z $RIGHT ]; ...
[: too many arguments
Hier expandiert $LEFT zu yes sir, also zu zwei Argumenten. Das test-Kommando will nach einem Argument auf jeden Fall einen Operator als naechstes Argument sehen und keinen weiteren nicht-Operator.
3.
LEFT="yes" RIGHT="we can" if [ $LEFT = "yes" ] && [ -z $RIGHT ]; ...
[: we: binary operator expected
Die Shell expandiert $RIGHT zu we can, also wieder zwei Argumente. Hier haette ich eigentlich auch "too many arguments" erwartet :) Anscheinend zaehlt test alle Argumente und guckt sich dann den Operator an. Da -z ein unaerer Operator ist, passt ihm das nicht.
Uebrigens: Weder "[ ... ]" noch "&&" gehoeren zur Syntax von "if".
"[" ist ein eigenstaendiges Kommando und heisst eigentlich "test". Es prueft Bedingungen (Ausdruecke) und gibt das Ergebnis als Exit Status zurueck. Beispiele:
test a = a ([ a = a ] ist das Gleiche) echo $? (Exit Status 0, wahr) [ "bla" = "blubb" ] (ja, eckige Klammer auf ist ein Kommando, eckige Klammer zu wird in diesem Fall als Abschluss erwartet) echo $? (Exit Status 1, falsch)
"&&" ist ein Konstrukt zum Verketten von Kommandos. Das Kommando links von && wird ausgefuehrt. Wenn dessen Exit Status 0 ist, wird auch das Kommando rechts von && ausgefuehrt. Beispiel:
ping -c2 8.8.8.8 && echo "google dns is reachable"
"if" fuehrt das nachfolgende als Kommando aus und prueft den Exit Status. Ist dieser 0 (okay), wird der von "then" ... "fi" geklammerte Block ausgefuehrt. Beispiel:
if grep -wq swap /etc/fstab ; then echo "swap found in fstab" touch /var/log/swap_last_found fi
Gruss, Chris
Hallo Christian,
vielen Dank für Deine ausführlichen Erklärungen, Dank auch an all die anderen.
Ich nehme also Qouting um die leere Variable als Ursache auszuschalten und ich könnte mich vom if - then - fi Konstrukt lösen, wenn ich nachfolgenden Befehle, die vom Ergebnis abhängen in begin - end kapsele (und keinen else Zweig benötige).
Mit freundlichen Grüßen / Kind regards Ronny Seffner
Ronny Seffner ronny@seffner.de (Fr 20 Jan 2012 13:05:31 CET):
Hallo Christian,
vielen Dank für Deine ausführlichen Erklärungen, Dank auch an all die anderen.
Ich nehme also Qouting um die leere Variable als Ursache auszuschalten und ich könnte mich vom if - then - fi Konstrukt lösen, wenn ich nachfolgenden Befehle, die vom Ergebnis abhängen in begin - end kapsele (und keinen else Zweig benötige).
Quoting nimmst Du immer, wenn Du nicht weißt, was in den Variablen steht.
begin/end? Was ist das? Ich denke, das war Pascal, oder?
Guten Abend Heiko,
begin/end? Was ist das? Ich denke, das war Pascal, oder?
Hmm, Pascal oder objektive pascal ist das, was ich wirklich kann, mit der bash weiß ich mir in der Regel zu helfen und perl kann ich teilweise lesen ;-)
Bei "if" ist die Sache klar, if -> else, if -> fi und else -> fi sind Begrenzer von Befehlsblöcken. Ich denke aber auch schon "(" und ")" um mehrere Befehle gesetzt zu haben um diese im Zusammenhang zu betrachten. Angenommen ich will in Abhängigkeit vom Ergebnis von "test" zwei Befehle, diese aber unabhängig von deren return ausführen, da nehme ich die Klammern (quasi als begin ... end)
'[ -e &file ] && (echo "delete $file"; rm $file)' - für mich liest sich "("=begin und ")"=end ;-)
Mit freundlichen Grüßen / Kind regards Ronny Seffner
Hallo,
Ronny Seffner ronny@seffner.de (Fr 20 Jan 2012 23:32:12 CET):
Guten Abend Heiko,
begin/end? Was ist das? Ich denke, das war Pascal, oder?
Bei "if" ist die Sache klar, if -> else, if -> fi und else -> fi sind Begrenzer von Befehlsblöcken. Ich denke aber auch schon "(" und ")" um mehrere Befehle gesetzt zu haben um diese im Zusammenhang zu betrachten. Angenommen ich will in Abhängigkeit vom Ergebnis von "test" zwei Befehle, diese aber unabhängig von deren return ausführen, da nehme ich die Klammern (quasi als begin ... end)
'[ -e &file ] && (echo "delete $file"; rm $file)' - für mich liest sich "("=begin und ")"=end ;-)
[ -e "$file" ] && (echo "delete $file"; rm "$file")
Ja, so kann man das betrachten, es gibt aber einen subtilen Unterschied zwischen ( cmd; cmd … ) und { cmd; cmd; …; }, ersteres findet in einer Subshell statt, letzteres dient nur zum Gruppieren und ist keine eigene Shell.
unset FOO; { FOO=bar; }; echo $FOO unset FOO; ( FOO=bar ); echo $FOO
Ronny Seffner ronny@seffner.de (Mi 18 Jan 2012 18:42:53 CET):
Gegeben sei:
LEFT="yes" RIGHT=""
if [ $LEFT = "yes" ] && [ -z $RIGHT ]; then ...
allerdings wirft das den Fehler:
-bash: [: =: Einstelliger (unärer) Operator erwartet.
Was habe ich nicht verstanden?
Mit genau jenen Settings funktioniert das bei mir. Zum Quoting hat ja Christian bereits einiges gesagt. Aber ich vermute, daß Dir das klar ist, ich meine, wie das mit dem Quoting gemeint ist.
Die von Dir vorgestellte Fehlermeldung kommt, wenn LEFT="" (oder gar nicht) gesetzt ist.
On 18.01.12 Heiko Schlittermann (hs@schlittermann.de) wrote:
Ronny Seffner ronny@seffner.de (Mi 18 Jan 2012 18:42:53 CET):
Moin,
Gegeben sei:
LEFT="yes" RIGHT=""
if [ $LEFT = "yes" ] && [ -z $RIGHT ]; then ...
allerdings wirft das den Fehler:
-bash: [: =: Einstelliger (unärer) Operator erwartet.
Was habe ich nicht verstanden?
Die von Dir vorgestellte Fehlermeldung kommt, wenn LEFT="" (oder gar nicht) gesetzt ist.
Zuweilen meine ich Konstrukte gesehen zu haben, wie
if [ x$LEFT = "xyes" ]...
Damit sollte sie das Problem umgehen lassen.
H.
Hilmar Preusse hille42@web.de (Mi 18 Jan 2012 22:29:13 CET):
On 18.01.12 Heiko Schlittermann (hs@schlittermann.de) wrote:
Ronny Seffner ronny@seffner.de (Mi 18 Jan 2012 18:42:53 CET):
Moin,
Gegeben sei:
LEFT="yes" RIGHT=""
if [ $LEFT = "yes" ] && [ -z $RIGHT ]; then ...
allerdings wirft das den Fehler:
-bash: [: =: Einstelliger (unärer) Operator erwartet.
Was habe ich nicht verstanden?
Die von Dir vorgestellte Fehlermeldung kommt, wenn LEFT="" (oder gar nicht) gesetzt ist.
Zuweilen meine ich Konstrukte gesehen zu haben, wie
if [ x$LEFT = "xyes" ]...
Damit sollte sie das Problem umgehen lassen.
Teilweise - Leerzeichen in Variablen führen dann immer noch zu Verwirrnis. Ich *denke*, es ging mit dem Prefix mehr um das Umschiffen von Bugs bei der Verarbeitung der leeren Zeichenketten.
lug-dd@mailman.schlittermann.de