Comprendre `echo $ ((0x63))`

18

Je cherchais un moyen de convertir hexadécimal via la ligne de commande et j'ai trouvé qu'il y avait une méthode très simple echo $((0x63)).

Cela fonctionne très bien, mais je suis un peu confus quant à ce qui se passe ici.

je sais $(...) c'est normalement un sous-shell, où le contenu est évalué avant la commande externe.

Est-ce toujours un sous-shell dans cette situation? Je ne pense pas que cela signifierait que le sous-shell évalue simplement (0x63)ce qui n'est pas une commande.

Quelqu'un peut-il décomposer la commande pour moi?

Philip Kirkbride
la source

Réponses:

27

$(...)est une substitution de commande (pas seulement un sous-shell), mais $((...))est une expansion arithmétique.

Lorsque vous utilisez $((...)), le... sera interprété comme une expression arithmétique. Cela signifie, entre autres, qu'une chaîne hexadécimale sera interprétée comme un nombre et convertie en décimal. L'expression entière sera alors remplacée par la valeur numérique à laquelle l'expression est évaluée.

Tout comme l'expansion des paramètres et la substitution de commandes, $((...))devrait être citée pour ne pas être affectée par la séparation des mots du shell et la globalisation du nom de fichier.

echo "$(( 0x63 ))"

En remarque, les variables apparaissant dans une expression arithmétique n'ont pas besoin de leur $:

$ x=030; y=30; z=0x30
$ echo "$(( x + y +x ))"
78
Kusalananda
la source
2
Notez également qu'en raison de $((...))conflits avec la substitution de commandes, il faut se rappeler d'écrire à la echo "$( (echo x; echo y) | tr xy yx)"place de echo "$((echo x; echo y) | tr xy yx)"(même si certains shells accepteront toujours cette dernière, YMMV).
Stéphane Chazelas
@ StéphaneChazelas Et comment faites-vous pour $(( ))produire une sortie qui est affectée par le fractionnement ou la globalisation des mots?
Hauke ​​Laging du
3
@HaukeLaging, IFS=9; echo $((0x63)). Voir aussi Conséquences pour la sécurité d'oublier de citer une variable dans des shells bash / POSIX ( What about [ $# -gt 1 ]section)
Stéphane Chazelas
3

Ce n'est pas une sous-coquille, mais une évaluation arithmétique. De man bash:

((expression))

L'expression est évaluée selon les règles décrites ci-dessous sous ÉVALUATION ARITHMÉTIQUE . Si la valeur de l'expression est différente de zéro, l'état de retour est 0; sinon le statut de retour est 1. C'est exactement équivalent à laisser "expression".

user4556274
la source
9
((...))n'est pas tout à fait la même chose que $((...)). Les deux font une évaluation arithmétique, mais cette dernière est remplacée par la valeur résultante sous forme de chaîne.
Kusalananda