2016-08-02 63 views
0

In einem Bash-Skript, habe ich die folgende Bedingung:Bash Integer und String bedingt mit && und || in if-Anweisung

if [ $cnt -eq 1 ] && [[ $str != *"something 1"* || $str != *"something 2"* ]] 

Es ist nicht wie erwartet funktioniert. Ist das in Bash möglich? Wenn ja, wie lautet die korrekte Syntax? Das gewünschte Verhalten ist, dass die if-Anweisung true zurückgibt, wenn $cnt -eq 1 wahr ist und entweder $str != *"something 1"* oder $str != *"something 2"* wahr ist.

+2

Die Syntax ist in Ordnung; Warum denkst du, dass es falsch ist? Geben Sie die Werte von $ cnt und $ str an, für die das Ergebnis nicht dem erwarteten Wert entspricht. – chepner

+1

well - '[$ cnt -eq 1]' ist nicht * ganz * gut, da es einen Syntaxfehler auslöst, anstatt etwas nützlicheres zu tun, wenn 'cnt' leer, nicht definiert oder auf mehrere Wörter erweitert ist. '[" $ cnt "-eq 1]' würde diese Fälle vermeiden, während '((cnt == 1))' sauberer zu lesen wäre (und einen nicht gesetzten Wert behandeln würde, als wäre es 0). Aber vorausgesetzt, dass es wirklich einen einzigen numerischen Wert in dieser Variablen gibt und "IFS" keine Ziffern enthält, die auch in dieser Zahl gefunden werden, dann wird das Fehlen von Anführungszeichen keinen unmittelbaren Fehler verursachen, also sind wir hier fehlt noch ein Reproduzierer. –

+0

... unverblümt: "Es funktioniert nicht" ist kein Fehlerbericht. –

Antwort

1

Dies ist kein Syntaxproblem, ich bin mir ziemlich sicher, dass es ein logisches Problem ist. Der Ausdruck [[ $str != *"something 1"* || $str != *"something 2"* ]] ist wahr, es sei denn, $str entspricht beide Muster. Bedenken Sie:

$ str="foo no pattern bar" 
$ [[ $str != *"something 1"* || $str != *"something 2"* ]] && echo true || echo false 
true 
$ str="foo something 1 bar" 
$ [[ $str != *"something 1"* || $str != *"something 2"* ]] && echo true || echo false 
true 
$ str="foo something 2 bar" 
$ [[ $str != *"something 1"* || $str != *"something 2"* ]] && echo true || echo false 
true 
$ str="foo something 1 something 2 bar" 
$ [[ $str != *"something 1"* || $str != *"something 2"* ]] && echo true || echo false 
false 

denke ich, was Sie wollen etwas, das wahr ist, wenn $str nicht so oder Muster übereinstimmt, die Sie && brauchen bedeutet, statt ||:

$ str="foo no pattern bar" 
$ [[ $str != *"something 1"* && $str != *"something 2"* ]] && echo true || echo false 
true 
$ str="foo something 1 bar" 
$ [[ $str != *"something 1"* && $str != *"something 2"* ]] && echo true || echo false 
false 
$ str="foo something 2 bar" 
$ [[ $str != *"something 1"* && $str != *"something 2"* ]] && echo true || echo false 
false 

Um zu verstehen, warum dies so ist, Scheck De Morgan's laws, von denen eine besagt, dass "nicht (A oder B)" dasselbe wie "(nicht A) und (nicht B)" ist.

+0

Hallo Gordon, du hast Recht! Der Wechsel von || zu && hat mein Problem behoben. Vielen Dank! – Nate650