Bash if-Anweisung mit mehreren Bedingungen löst einen Fehler aus

165

Ich versuche, ein Skript zu schreiben, das zwei Fehlerflags überprüft. Wenn ein Flag (oder beide) geändert werden, wird ein Echo ausgegeben - ein Fehler ist aufgetreten. Mein Skript:

my_error_flag=0
my_error_flag_o=0
do something.....
if [[ "$my_error_flag"=="1" || "$my_error_flag_o"=="2" ] || [ "$my_error_flag"="1" &&     "$my_error_flag_o"="2" ]]; then
    echo "$my_error_flag"
else
    echo "no flag"
fi

Grundsätzlich sollte es etwas sein:

if ((a=1 or b=2) or (a=1 and b=2))
  then
     display error
else
     no error
fi

Der Fehler, den ich bekomme, ist:

 line 26: conditional binary operator expected
 line 26: syntax error near `]'
 line 26: `if [[ "$my_error_flag"=="1" || "$my_error_flag_o"=="2" ] || [ "$my_error_flag"="1" && "$my_error_flag_o"="2" ]]; then'

Sind meine Klammern durcheinander?

Einfach ich
quelle
Überprüfen Sie dies heraus: theunixshell.blogspot.com/2013/05/…
Vijay
2
Verwenden Sie Klammern - ()
AlikElzin-kilaka
3
Logischerweise a==1 or b==2deckt bereits der Fall ab, in dem a==1 and b==2. Separat zu testen ist hier völlig überflüssig.
Tripleee

Antworten:

247

Verwenden Sie -a(für und) und -o(für oder) Operationen.

tldp.org/LDP/Bash-Beginners-Guide/html/sect_07_01.html

Aktualisieren

Eigentlich könnte man noch verwenden &&und ||mit dem -eqBetrieb. Ihr Skript würde also so aussehen:

my_error_flag=1
my_error_flag_o=1
if [ $my_error_flag -eq 1 ] ||  [ $my_error_flag_o -eq 2 ] || ([ $my_error_flag -eq 1 ] && [ $my_error_flag_o -eq 2 ]); then
      echo "$my_error_flag"
else
    echo "no flag"
fi

Obwohl Sie in Ihrem Fall die letzten beiden Ausdrücke verwerfen und einfach bei einem oder einer Operation wie dieser bleiben können:

my_error_flag=1
my_error_flag_o=1
if [ $my_error_flag -eq 1 ] ||  [ $my_error_flag_o -eq 2 ]; then
      echo "$my_error_flag"
else
    echo "no flag"
fi
mkhatib
quelle
3
@Simply_Me: Nein, ein logisches ODER ist wahr, wenn einer oder beide seiner Operanden wahr sind. Sie denken an "exklusiv oder" (XOR), was wahr ist, wenn genau einer seiner Operanden wahr ist. (Tatsächlich gibt es Versionen von XOR, die mit mehr als 2 Operanden arbeiten. In diesem Fall ist es wahr, wenn eine ungerade Anzahl von Operanden wahr ist.)
Gordon Davisson
4
Übrigens, Probleme im ursprünglichen Code sind das Verwenden [und ]Gruppieren (das tun sie nicht) und das Nicht-Platzieren von Leerzeichen um den Operator (z. B. "$my_error_flag"="1"), wodurch verhindert wird, dass die Shell ihn überhaupt als Operator erkennt. Bitte lesen Sie BashFAQ Nr. 17 (zur Gruppierung) und Nr. 31 (zum Unterschied zwischen verschiedenen Arten von Testausdrücken ) . In diesem Fall wäre es sogar noch einfacher, einen arithmetischen Ausdruck zu verwenden .
Gordon Davisson
7
-aund -owerden von der POSIX-Spezifikation als veraltet angesehen ; Verwenden Sie separate Tests in Kombination mit ||wie im Update.
Chepper
1
Keine Gruppierung mit Subshells erforderlich, normalerweise {}sollte auch eine Gruppierung mit Subshells möglich sein.
Phk
1
Um den obigen Kommentar von phk zu ergänzen, startet () Subshells in Bash, die alle möglichen subtilen [wahrscheinlich unerwünschten] Effekte haben können.
Brett
70

Sie können entweder [[oder ein ((Schlüsselwort verwenden. Wenn Sie ein [[Schlüsselwort verwenden, müssen Sie Zeichenfolgenoperatoren wie -eq, -lt. Ich denke, ((ist am meisten für die Arithmetik bevorzugt, da Sie direkt Operatoren wie verwenden können ==, <und >.

Mit [[Operator

a=$1
b=$2
if [[ a -eq 1 || b -eq 2 ]] || [[ a -eq 3 && b -eq 4 ]]
then
     echo "Error"
else
     echo "No Error"
fi

Mit ((Operator

a=$1
b=$2
if (( a == 1 || b == 2 )) || (( a == 3 && b == 4 ))
then
     echo "Error"
else
     echo "No Error"
fi

Nicht verwenden -aoder -oOperatoren Da es nicht tragbar ist.

Fizer Khan
quelle
8

Bitte versuchen Sie Folgendes

if ([ $dateR -ge 234 ] && [ $dateR -lt 238 ]) || ([ $dateR -ge 834 ] && [ $dateR -lt 838 ]) || ([ $dateR -ge 1434 ] && [ $dateR -lt 1438 ]) || ([ $dateR -ge 2034 ] && [ $dateR -lt 2038 ]) ;
then
    echo "WORKING"
else
    echo "Out of range!"
Manash Nath
quelle
2
( ... )erstellt Unterschalen - viele Auswirkungen auf die Leistung ohne Nutzen.
Charles Duffy
4
Verwenden Sie { ...; }für ohne Subshell Erstellung gruppieren.
Charles Duffy
1

Sie können sich inspirieren lassen, indem Sie ein entrypoint.sh Skript lesen, das von den Mitwirkenden von MySQL geschrieben wurde und prüft, ob die angegebenen Variablen festgelegt wurden.

Wie das Skript zeigt, können Sie sie mit folgenden -aPunkten versehen: z.

if [ -z "$MYSQL_ROOT_PASSWORD" -a -z "$MYSQL_ALLOW_EMPTY_PASSWORD" -a -z "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then
    ...
fi
Daniel Andrei Mincă
quelle
1
-aist in der aktuellen Version des POSIX- testStandards als veraltet markiert ; Siehe die OBMarkierungen unter pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html . Verwenden Sie [ -z "$FOO" ] && [ -z "$BAR" ]diese Option , um einen zuverlässigeren Code zu erhalten.
Charles Duffy