Grundlegendes zu "echo $ ((0x63))"

18

Ich suchte nach einer Möglichkeit, Hexadezimalzahlen über die Befehlszeile zu konvertieren, und fand heraus, dass es eine sehr einfache Methode gibt echo $((0x63)).

Es funktioniert großartig, aber ich bin ein wenig verwirrt darüber, was hier passiert.

Ich weiß, $(...)ist normalerweise eine Unterschale, in der der Inhalt vor dem äußeren Befehl ausgewertet wird.

Ist es in dieser Situation immer noch eine Unterschale? Ich denke nicht, dass dies bedeuten würde, dass die Sub-Shell nur auswertet, (0x63)was kein Befehl ist.

Kann jemand den Befehl für mich auflösen?

Philip Kirkbride
quelle

Antworten:

27

$(...)ist eine Befehlsersetzung (nicht nur eine Subshell), sondern $((...))eine arithmetische Erweiterung.

Wenn Sie verwenden $((...)), ...wird das als arithmetischer Ausdruck interpretiert. Dies bedeutet unter anderem, dass eine hexadezimale Zeichenfolge als Zahl interpretiert und in eine Dezimalzahl konvertiert wird. Der gesamte Ausdruck wird dann durch den numerischen Wert ersetzt, den der Ausdruck ergibt.

Ebenso wie die Parametererweiterung und die Befehlssubstitution $((...))sollte angegeben werden, dass sie nicht von der Wortteilung und der Dateinamenverschiebung der Shell betroffen sind.

echo "$(( 0x63 ))"

Nebenbei bemerkt, Variablen, die in einem arithmetischen Ausdruck vorkommen, brauchen nicht $:

$ x=030; y=30; z=0x30
$ echo "$(( x + y +x ))"
78
Kusalananda
quelle
2
Beachten Sie auch, dass Sie sich wegen $((...))Konflikten mit der Befehlsersetzung daran erinnern müssen, echo "$( (echo x; echo y) | tr xy yx)"statt zu schreiben echo "$((echo x; echo y) | tr xy yx)"(auch wenn einige Shells das letztere weiterhin akzeptieren, YMMV).
Stéphane Chazelas
@ StéphaneChazelas Und wie lässt sich $(( ))eine Ausgabe produzieren, die von Worttrennung oder Globbing betroffen ist?
Hauke ​​Laging
3
@HaukeLaging, IFS=9; echo $((0x63)). Siehe auch Auswirkungen auf die Sicherheit, wenn Sie vergessen, eine Variable in bash / POSIX-ShellsWhat about [ $# -gt 1 ]
anzugeben
3

Dies ist keine Unterschale, sondern eine arithmetische Auswertung. Von man bash:

((Ausdruck))

Der Ausdruck wird gemäß den nachstehend unter ARITHMETISCHE BEWERTUNG beschriebenen Regeln ausgewertet . Wenn der Wert des Ausdrucks nicht Null ist, ist der Rückgabestatus 0; Andernfalls lautet der Rückgabestatus 1. Dies ist genau gleichbedeutend mit let "expression".

user4556274
quelle
9
((...))ist nicht ganz das gleiche wie $((...)). Beide führen eine arithmetische Auswertung durch, wobei letztere durch den resultierenden Wert als Zeichenfolge ersetzt wird.
Kusalananda