Memahami `echo $ ((0x63))`


18

Saya sedang mencari cara untuk mengkonversi heksadesimal melalui baris perintah dan menemukan ada metode yang sangat mudah echo $((0x63)).

Ini bekerja dengan baik tetapi saya agak bingung dengan apa yang terjadi di sini.

Saya tahu $(...)biasanya sub-shell, di mana isinya dievaluasi sebelum perintah luar.

Apakah ini masih menjadi sub-shell dalam situasi ini? Saya berpikir tidak karena itu berarti sub-shell hanya mengevaluasi (0x63)yang bukan perintah.

Bisakah seseorang meruntuhkan perintah untuk saya?

Jawaban:


27

$(...)adalah substitusi perintah (bukan hanya subkulit), tetapi $((...))merupakan ekspansi aritmatika.

Saat Anda menggunakan $((...)), ...akan ditafsirkan sebagai ekspresi aritmatika. Ini berarti, antara lain, bahwa string heksadesimal akan ditafsirkan sebagai angka dan dikonversi menjadi desimal. Seluruh ekspresi kemudian akan diganti dengan nilai numerik yang dievaluasi oleh ekspresi itu.

Seperti ekspansi parameter dan substitusi perintah, $((...))harus dikutip agar tidak terpengaruh oleh pemisahan kata shell dan penggumpalan nama file.

echo "$(( 0x63 ))"

Sebagai catatan tambahan, variabel yang muncul dalam ekspresi aritmatika tidak perlu $:

$ x=030; y=30; z=0x30
$ echo "$(( x + y +x ))"
78

2
Juga perhatikan bahwa karena $((...))konflik dengan substitusi perintah, kita harus ingat untuk menulis echo "$( (echo x; echo y) | tr xy yx)"alih-alih echo "$((echo x; echo y) | tr xy yx)"(walaupun beberapa shell masih akan menerima yang terakhir, YMMV).
Stéphane Chazelas

@ StéphaneChazelas Dan bagaimana Anda membuat $(( ))output yang dipengaruhi oleh pemisahan kata atau globbing?
Hauke ​​Laging

3
@ HaukeLaging IFS=9; echo $((0x63)),. Lihat juga Implikasi keamanan dari lupa mengutip variabel dalam bash / POSIX shells ( What about [ $# -gt 1 ]bagian)
Stéphane Chazelas

3

Ini bukan subkulit, tetapi evaluasi aritmatika. Dari man bash:

((ekspresi))

Ekspresi dievaluasi sesuai dengan aturan yang dijelaskan di bawah ini di bawah EVALUASI ARITHMETIC . Jika nilai ekspresi bukan nol, status pengembalian adalah 0; jika tidak, status pengembaliannya adalah 1. Ini persis sama dengan membiarkan "ekspresi".


9
((...))tidak persis sama dengan $((...)). Keduanya melakukan evaluasi aritmatika, tetapi yang terakhir digantikan oleh nilai yang dihasilkan sebagai string.
Kusalananda
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.