Vergleichen von ganzen Zahlen: arithmetischer Ausdruck oder bedingter Ausdruck

In Bash können zwei ganze Zahlen mit dem bedingten Ausdruck

arg1 OP arg2

OP ist eines von -eq, -ne, -lt, -le, -gt oder -ge. Diese arithmetischen Binäroperatoren geben true zurück, wenn arg1 gleich, nicht gleich, kleiner als, kleiner als oder gleich, größer als oder größer als oder gleich arg2 ist. beziehungsweise. Arg1 und arg2 können positive oder negative Ganzzahlen sein.

oder arithmetischer Ausdruck:

<= >= < > Vergleich

== != Gleichheit und Ungleichung

Warum gibt es zwei verschiedene Möglichkeiten, zwei ganze Zahlen zu vergleichen? Wann soll welcher verwendet werden?

Beispielsweise verwendet [[ 3 -lt 2 ]] einen bedingten Ausdruck und (( 3 < 2 )) einen arithmetischen Ausdruck. Beide geben 0 zurück, wenn der Vergleich wahr ist.

Können diese beiden Methoden beim Vergleich zweier Ganzzahlen immer austauschbar verwendet werden? Wenn ja, warum hat Bash zwei Methoden anstatt einer?

Kommentare

  • = != < <= > >= Vergleiche Zeichenfolgen . 1 -eq 01 aber 1 != 01 und 8 -lt 42 aber 8 > 42
  • Sie sind in arithmetischen Ausdrücken überladen.
  • Sie ‚ müssen in den Bash-Änderungsprotokollen suchen, um herauszufinden, wann die einzelnen Funktionen vorhanden waren hinzugefügt. Ich vermute, dass die arithmetischen Ausdrücke viel später als der Testbefehl hinzugefügt wurden.
  • Ich frage nicht nach dem Vergleichen von Zeichenfolgen. @muru.

Antwort

Ja, wir haben zwei verschiedene Möglichkeiten, zwei ganze Zahlen zu vergleichen.

Es scheint, dass diese Fakten in diesem Forum nicht allgemein akzeptiert werden:

  1. Innerhalb der Redewendung [ ] sind die Operatoren für den arithmetischen Vergleich -eq, -ne, -lt, -le, -gt und -ge.

    Da sie sich auch in einem Testbefehl und in einer [[ ]].

    Ja, innerhalb dieser Redewendungen sind =, < usw. Zeichenfolgenoperatoren.

  2. Innerhalb des Idioms (( )) sind die Operatoren für den arithmetischen Vergleich == , !=, <, <=, > und >=.

    Nein, dies ist kein „Arithmus“ etische Erweiterung „(die mit einem $ beginnt) als $(( )). Es wird als „zusammengesetzter Befehl“ in man bash definiert.

    Ja, es folgt den gleichen Regeln (intern) der „arithmetischen Erweiterung“, hat jedoch keine Ausgabe, nur einen Exit-Wert. Es könnte folgendermaßen verwendet werden:

if (( 2 > 1 )); then ... 

Warum haben wir zwei verschiedene Möglichkeiten, zwei ganze Zahlen zu vergleichen?

Ich denke, dass letzteres (( )) als einfachere Methode zur Durchführung von arithmetischen Tests entwickelt wurde. Es ist fast dasselbe wie das $(( )), hat aber nur keine Ausgabe.

Warum zwei? Genauso wie wir zwei printf (extern und eingebaut) oder vier Tests (extern test, eingebaut , [ und [[). Auf diese Weise wachsen die Muscheln, verbessern einen Bereich in einem Jahr und verbessern einen anderen im nächsten Jahr.

Wann welche verwenden?

Das ist eine sehr schwierige Frage, weil Es sollte keinen effektiven Unterschied geben. Natürlich gibt es einige Unterschiede in der Art und Weise, wie eine [ ] und eine (( )) intern funktionieren, aber: Was ist besser, um zwei ganze Zahlen zu vergleichen? Beliebig!

Können diese beiden Methoden beim Vergleich zweier Ganzzahlen immer austauschbar verwendet werden?

Für zwei Zahlen muss ich Ja sagen.
Aber für Variablen Erweiterungen Bei mathematischen Operationen kann es wesentliche Unterschiede geben, die den einen oder anderen begünstigen sollten. Ich kann nicht sagen, dass absolut beide gleich sind. Zum einen könnte die (( )) mehrere mathematische Operationen nacheinander ausführen:

if (( a=1, b=2, c=a+b*b )); then echo "$c"; fi 

Wenn ja, warum hat Bash zwei Methoden statt einer?

Wenn beide hilfreich sind, warum nicht?

Kommentare

  • = ist eine Zuweisung und == ist ein Vergleich in arithmetischen Erweiterungen. Die Frage zitiert es richtig. Aber die Antwort ist falsch.
  • Auch ( ist kein reserviertes Wort in bash, daher müssen keine Leerzeichen um ((, as gesetzt werden im Gegensatz zu [ oder [[

Antwort

Historisch gesehen war der Befehl test zuerst vorhanden (mindestens bis zu Unix Seventh Edition 1979). Es wurden die Operatoren = und != zum Vergleichen von Zeichenfolgen und -eq, -ne, -lt usw., um Zahlen zu vergleichen. Beispiel: test 0 = 00 ist falsch, aber test 0 -eq 00 ist wahr. Ich weiß nicht, warum diese Syntax gewählt wurde, aber möglicherweise wurde vermieden, < und > zu verwenden, die die Shell hätte Als Umleitungsoperatoren analysiert. Der Befehl test erhielt einige Jahre später eine andere Syntax: [ … ] entspricht test ….

Die bedingte Syntax [[ … ]], in der < und > kann als Operator ohne Anführungszeichen verwendet werden, wurde später in ksh hinzugefügt. Die Abwärtskompatibilität mit [ … ] wurde beibehalten, sodass dieselben Operatoren verwendet wurden, jedoch < und > zum Vergleichen von Zeichenfolgen (z. B. [[ 9 > 10 ]], aber [[ 9 -lt 10 ]]) Weitere Informationen finden Sie unter mit einfacher oder doppelter Klammer – bash

Arithmetische Ausdrücke kamen auch später als test Befehl,

in der Korn-Shell , irgendwann in den 1980er Jahren. Sie folgten der Syntax der C-Sprache, die in Unix-Kreisen sehr beliebt war. Daher verwendeten sie die Operatoren von C:==für Gleichheit,<=für weniger oder gleich usw.

Unix Seventh Edition hatte keine arithmetischen Ausdrücke, aber den Befehl expr , der auch a implementierte C-ähnliche Syntax für ganzzahlige Operationen, einschließlich ihrer Vergleichsoperatoren. In einem Shell-Skript mussten die Zeichen < und > in Anführungszeichen gesetzt werden, um sie vor der Shell zu schützen, z. if expr 1 \< 2; … entspricht if test 1 -lt 2; …. Das Hinzufügen von arithmetischen Ausdrücken zur Shell machte die meisten Verwendungen von expr veraltet, so dass es heute nicht „bekannt“ ist.

In einem sh-Skript, Sie “ d Verwenden Sie im Allgemeinen arithmetische Ausdrücke, um einen ganzzahligen Wert zu berechnen, und [ … ], um Ganzzahlen zu vergleichen.

if [ "$((x + y))" -lt "$z" ]; then … 

In einem ksh , Bash- oder Zsh-Skript, Sie können ((…)) für beide verwenden.

if ((x + y < z)); then … 

Die [[ … ]] -Formular ist nützlich, wenn Sie Bedingungen verwenden möchten, die andere Dinge als Ganzzahlen betreffen.

Antwort

Entsprechend Die Test-Manpage = und! = werden für Zeichenfolgenvergleiche verwendet, während die Ausdrücke -eq, -gt, -lt, -ge, -le und -ne ganzzahlige Vergleiche sind. Ich habe diese Konvention beim Schreiben von Shell-Skripten immer befolgt und sie funktioniert immer. Beachten Sie, dass Sie die Variablen möglicherweise in Anführungszeichen setzen müssen, wenn Sie Variablen im Ausdruck haben, um einen Nullvergleich zu vermeiden.

Auf dem Papier führen wir Zeichenfolgen- / Zahlenvergleiche ohne viel Nachdenken durch. Ein Computer hingegen weiß nicht, ob 987 eine Zahl oder eine Zeichenfolge ist. Die verschiedenen Bediener müssen dem Computer mitteilen, was zu tun ist, damit Sie das richtige Ergebnis erhalten. Es gibt einige zusätzliche Informationen hier , die einen Teil der Geschichte erklären. Im Wesentlichen sind die Variablen untypisiert und aus Gründen der historischen Kompatibilität so geblieben.

Kommentare

  • In meinem Beitrag = und != sind arithmetische Operatoren, während die Manpage von test nur Operatoren für bedingte Ausdrücke anzeigt.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.