expr
scheint Klammern nicht zu mögen (wird in der Mathematik verwendet, um die Operatorpriorität zu explizieren):
expr 3 * (2 + 1)
bash: syntax error near unexpected token `('
Wie drücke ich die Operatorpriorität in bash aus?
shell
quoting
arithmetic
expr
Nicolas Raoul
quelle
quelle
let
. Es ist nicht standardmäßiger oder portabler als(( a = 3 * (2 + 1) ))
(beide kommen vonksh
und sind nur in ksh, bash und zsh verfügbar) und es ist weniger lesbar oder leicht zu zitieren. Gebraucha=$((3 * (2 + 1)))
, beweglich zu sein.((a = 3 * (2 + 1) ))
, eine für Portabilitäta=$((3 * (2 + 1)))
), es ist also keine Notiz gegen Sie oder Ihre Antwort, sondern dagegen, dass es die ausgewählte Antwort ist und Torschützenkönig.a=1 $[a+2]
odera=1 b=2 $[a+b]
. Ist ihr Grund, diese Syntax zu vermeiden?Sie können stattdessen die arithmetische Erweiterung verwenden.
Meiner persönlichen Meinung nach sieht das ein bisschen besser aus als mit
expr
.Von
man bash
quelle
Es gibt keinen Grund,
expr
in modernen Schalen für das Rechnen zu verwenden.POSIX definiert den
$((...))
Expansionsoperator. Sie können das also in allen POSIX-kompatiblen Shells verwenden (diesh
aller modernen Unix-Likes, Dash, Bash, Yash, Mksh, Zsh, Posh, Ksh ...).ksh
Außerdem wurde einlet
Builtin eingeführt, das denselben arithmetischen Ausdruck übergibt, nicht zu etwas erweitert, sondern einen Exit-Status zurückgibt, der davon abhängt, ob der Ausdruck in 0 aufgelöst wird oder nicht, wie inexpr
:Da das Zitat jedoch umständlich und nicht sehr leserlich ist (nicht im gleichen Maße wie
expr
natürlich), wurdeksh
auch eine((...))
alternative Form eingeführt:Das ist viel besser lesbar und sollte stattdessen verwendet werden.
let
und((...))
sind nur inksh
,zsh
undbash
. Die$((...))
Syntax sollte bevorzugt werden, wenn die Portierbarkeit auf andere Shells erforderlich ist. Diesexpr
ist nur für Bourne-ähnliche Shells vor POSIX erforderlich (normalerweise die Bourne-Shell oder frühe Versionen der Almquist-Shell).An der Nicht-Bourne-Front gibt es einige Shells mit integriertem arithmetischen Operator:
csh
/tcsh
(eigentlich die erste Unix-Shell mit integrierter arithmetischer Auswertung):akanga
(basierend aufrc
)als geschichtsnotiz hatte die originalversion der Almquist-shell, wie sie 1989 im Usenet veröffentlicht wurde, einen
expr
eingebauten (tatsächlich zusammengeführtentest
), der jedoch später entfernt wurde.quelle
: $((a = a*2))
?$((...))
wie zsh, ksh93 oder yash unterstützt.expr
ist ein externer Befehl, keine spezielle Shell-Syntax. Wenn Sieexpr
Shell-Sonderzeichen sehen möchten , müssen Sie sie daher vor Shell-Analyse schützen, indem Sie sie in Anführungszeichen setzen. Darüber hinausexpr
muss jede Nummer und jeder Operator als separater Parameter übergeben werden. Somit:Sofern Sie nicht an einem antiken Unix-System aus den 1970er oder 1980er Jahren arbeiten, gibt es nur sehr wenige Gründe, es zu verwenden
expr
. Früher hatten Shells keine eingebaute Methode zum Rechnen, und Sie musstenexpr
stattdessen das Dienstprogramm aufrufen . Alle POSIX-Shells verfügen über eine integrierte Arithmetik über die arithmetische Erweiterungssyntax .Das Konstrukt
$((…))
expandiert zum Ergebnis des arithmetischen Ausdrucks (in Dezimalschrift geschrieben). Bash unterstützt wie die meisten Shells nur Ganzzahl-Arithmetikmodule 2 64 (oder Modulo 2 32 für ältere Versionen von Bash und einige andere Shells auf 32-Bit-Computern).Bash bietet eine zusätzliche Komfortsyntax, wenn Sie Zuweisungen ausführen oder testen möchten, ob ein Ausdruck 0 ist, aber das Ergebnis nicht berücksichtigt. Dieses Konstrukt existiert auch in ksh und zsh, aber nicht in plain sh.
Bietet zusätzlich zur Ganzzahlarithmetik
expr
einige Funktionen zur Manipulation von Zeichenfolgen. Auch diese werden von den Funktionen der POSIX-Shells zusammengefasst, mit einer Ausnahme:expr STRING : REGEXP
Prüft, ob die Zeichenfolge mit dem angegebenen regulären Ausdruck übereinstimmt. Eine POSIX-Shell kann dies nicht ohne externe Tools tun, aber Bash kann mit[[ STRING =~ REGEXP ]]
(mit einer anderen Regexp-Syntax -expr
ist ein klassisches Tool und verwendet BRE, Bash verwendet ERE).Sofern Sie keine Skripte verwalten, die auf 20 Jahre alten Systemen ausgeführt werden, müssen Sie nicht wissen, dass es diese
expr
jemals gab. Verwenden Sie Shell-Arithmetik.quelle
expr foo : '\(.\)'
Führt auch die Textextraktion durch.bash
'sBASH_REMATCH
schafft sowas ähnliches. Es führt auch einen Zeichenfolgenvergleich durch, den POSIX[
nicht durchführt (obwohl man sich Möglichkeiten vorstellen könnte, dies zu tunsort
).Verwenden Sie Klammern mit Anführungszeichen:
Die Anführungszeichen verhindern, dass Bash die Klammern als Bash-Syntax interpretiert.
quelle
expr
Befehlszeile durch Leerzeichen getrennt sein müssen. damit; zum Beispielexpr 3 "*" "(2" "+" "1)"
wird nicht funktionieren . (Übrigens müssen Sie das wahrscheinlich nicht zitieren+
.)while
und[[
, sie sind Syntax. Wären sie Schlüsselwörter, würden sie in Befehlsargumenten nicht als solche interpretiert. Sie benötigen Anführungszeichen, damit bash sie nicht analysiert, sondern stattdessen ein Zeichenfolgenliteral anzeigt.Wenn Sie bc haben ..
quelle