Mit expr, $ (()), (())

Im Shell-Skript können wir expr $a*$b durch ersetzen $(($a+$b)).

Aber warum nicht einfach mit (($a+$b)), denn in jeder Ressource steht geschrieben, dass (()) für die Ganzzahlberechnung vorgesehen ist.

Also verwenden wir $(()), wenn es Variablen anstelle von ganzzahligen Werten gibt, oder? Und was sollten wir anstelle von $(()) verwenden, wenn Variablen Gleitkommawerte empfangen können?

Kommentare

Antwort

  1. Für die Arithmetik ist expr archaisch. Verwenden Sie es nicht. *

  2. $((...)) und ((...)) sind sehr ähnlich. Beide führen nur ganzzahlige Berechnungen durch. Der Unterschied besteht darin, dass $((...)) das Ergebnis der Berechnung zurückgibt und ((...)) dies nicht tut. Also $((...)) ist nützlich in echo -Anweisungen:

    $ a=2; b=3; echo $((a*b)) 6 

    ((...)) ist nützlich, wenn Sie eine Variable zuweisen oder einen Exit-Code festlegen möchten:

    $ a=3; b=3; ((a==b)) && echo yes yes 
  3. Wenn Sie schweben möchten Punktberechnungen verwenden Sie bc oder awk:

    $ echo "4.7/3.14" | bc -l 1.49681528662420382165 $ awk "BEGIN{print 4.7/3.14}" 1.49682 

* Abgesehen davon bleibt expr nützlich für die Zeichenfolgenbehandlung, wenn Globs nicht gut genug sind und eine POSIX-Methode für die Verarbeitung regulärer Ausdrücke erforderlich ist.

Kommentare

  • Wenn Ausdruck archaisch ist, was sollten wir anstelle von Ausdruckstext verwenden: '. *
  • Wenn s eine Shell-Variable ist, beträgt ihre Länge ${#s}
  • $ {#} bedeutet eine Anzahl von Argumenten und $ (# s} bedeutet eine Anzahl von Zeichen einer Variablen, oder?
  • Ja. Das ' ist richtig.
  • @Stranger Viele Verwendungen von expr STRING : REGEX können als . expr ist nur nützlich, wenn REGEX ' nicht mit Shell-Platzhaltern ausgedrückt werden kann.

Antwort

Ausdruck ist alt, hat aber eine begrenzte Verwendung, die ich mir vorstellen kann. Angenommen, Sie möchten eine Zeichenfolge suchen. Wenn Sie POSIX mit grep beibehalten möchten, müssen Sie eine Pipe verwenden:

if echo november | grep nov then : do something fi 

expr kann dies ohne Pipe tun:

if expr november : nov then : do something fi 

Der einzige Haken ist, dass Ausdruck mit verankerten Zeichenfolgen funktioniert. Wenn Sie also nach dem Beginn übereinstimmen möchten, müssen Sie den REGEXP ändern:

if expr november : ".*ber" then : do something fi 

In Bezug auf (( )) ist dieses Konstrukt kein POSIX und sollte daher vermieden werden.

In Bezug auf $(( )) müssen Sie das Dollarzeichen nicht einfügen:

$ fo=1 $ go=2 $ echo $((fo + go)) 3 

Kommentare

  • Viele Verwendungen von expr STRING : REGEX können als case STRING in PATTERN) geschrieben werden. expr ist nur nützlich, wenn REGEX ' nicht mit Shell-Platzhaltern ausgedrückt werden kann.

Antwort

Es scheint, dass die folgenden Programme mehr oder weniger dasselbe tun und sich nicht wirklich unterscheiden. Aber das ist nicht wahr.

#!/bin/bash s=-1000 for (( i=0; i<1000000; i++ )), do s=$((s+1)) echo $s 

Dies ist der richtige Weg, um dies zu implementieren. Der Ausdruck s + 1 wird von der Shell ausgewertet und kann einer Variablen zugewiesen werden.

#!/bin/bash s=-1000 for (( i=0; i<1000000; i++ )), do s=`expr $s+1` echo $s 

Hier wird der Ausdruck vom Programmausdruck berechnet, der keine eingebaute Shell, sondern ein externes Unix-Programm ist. Anstatt einfach 1 und s zu addieren, muss ein Programm gestartet und seine Ausgabe gelesen und in die Variable geschrieben werden. Das Starten eines Programms erfordert viele Ressourcen und viel Zeit. Und dieses Programm wird 1000000 Mal ausgeführt. Das Programm wird also viel langsamer sein als das vorherige. Trotzdem funktioniert der Code korrekt.

#!/bin/bash -e s=-1000 for (( i=0; i<1000000; i++ )), do ((s=s+1)) echo $s 

Wenn das Flag -e nicht gesetzt ist, funktioniert das Programm auch korrekt. Wenn -e jedoch gesetzt ist, wenn s = -1 und ((s = s + 1)) wird berechnet. Der Ausdruck s = s + 1 ergibt 0 und der Exit-Code von ((0)) ist> 0, was von der Shell und als Fehler interpretiert wird Die Shell beendet das Programm.

Der Grund für das Setzen des Flags -e ist, dass dies die einfachste Art der Fehlerverarbeitung ist: Beenden Sie, wenn ein Fehler auftritt.

Schreibe einen Kommentar

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