Apa tepatnya echo $ ((2 # $ 1))?

53

Skrip bash berikut menampilkan angka desimal saat diberi nomor biner.

echo $((2#$1))

Kenapa tepatnya?

Saya mengerti itu $1adalah input. Mungkin 2basis (biner). Tapi saya tidak bisa mengerti sintaks yang digunakan.

NanoPish
sumber

Jawaban:

72

bash bash

   echo [-neE] [arg ...]
          Output  the  args,  separated  by spaces, followed by a newline.
          The return status is 0 unless a write error occurs.   If  -n  is
          specified, the trailing newline is suppressed.  If the -e option
          is given,  interpretation  of  the  following  backslash-escaped
          characters  is  enabled.

[...]

   Arithmetic Expansion
       Arithmetic  expansion allows the evaluation of an arithmetic expression
       and the substitution of the result.  The format for  arithmetic  expan‐
       sion is:

              $((expression))

[...]

   Constants with a leading 0 are interpreted as octal numbers.  A leading
   0x or  0X  denotes  hexadecimal.   Otherwise,  numbers  take  the  form
   [base#]n,  where the optional base is a decimal number between 2 and 64
   representing the arithmetic base, and n is a number in that  base.   If
   base#  is omitted, then base 10 is used.  When specifying n, the digits
   greater than 9 are represented by the lowercase letters, the  uppercase
   letters, @, and _, in that order.  If base is less than or equal to 36,
   lowercase and uppercase letters may be used interchangeably  to  repre‐
   sent numbers between 10 and 35.
Ipor Sircer
sumber
66
-1 untuk penjelasan NOL.
Max Ried
27
Saya kira ini dijelaskan dengan cukup baik
NanoPish
19
Sepenuhnya menjawab pertanyaan, bahkan jika "hanya" dengan membuat dokumentasi yang ada, tidak layak -1 untuk saya. Khususnya jika dokumentasi itu adalah halaman manual bash.
YoungFrog
31
man bash | wcmenunjukkan halaman manual [GNU bash, versi 3.2.57] menjadi 4890 baris, 37094 kata , 329778 karakter. Jawaban ini menghilangkan hanya ke 7 baris, 176 kata , 1115 karakter yang relevan. Saya pikir jawaban itu patut Anda pilih. (seperti halnya komentar ini ;-)
Bruno Bronosky
7
@MaxRied: -1 ke komentar Anda untuk mencari bulu yang tidak perlu
Mehrdad
30

Dari Doc di: https://tiswww.case.edu/php/chet/bash/bashref.html#Shell-Arithmetic

Konstanta dengan awalan 0 ditafsirkan sebagai angka oktal. Sebuah '0x' atau '0X' yang memimpin menunjukkan heksadesimal. Kalau tidak, angka-angkanya mengambil bentuk [basis #] n, di mana basis opsional adalah angka desimal antara 2 dan 64 yang mewakili basis aritmatika, dan n adalah angka dalam basis itu. Jika basis # dihilangkan, maka basis 10 digunakan. Saat menentukan n, digit lebih besar dari 9 diwakili oleh huruf kecil, huruf besar, '@', dan '_', dalam urutan itu. Jika basis kurang dari atau sama dengan 36, huruf kecil dan huruf besar dapat digunakan secara bergantian untuk mewakili angka antara 10 dan 35.

Jadi echo $((16#FF))keluaran 255dan echo $((2#0110))keluaran6

ini singkat
sumber
25

Jawaban Ipor luar biasa tetapi sedikit tidak lengkap. Bagian yang dikutip dari halaman bash man menyatakan bahwa sintaks hanya berfungsi untuk konstanta, dan bukan konstanta. Anda harus bertanya bagaimana ini benar-benar berfungsi![base#]n2#$1

EKSPANSI

    Ekspansi dilakukan pada baris perintah setelah dipecah menjadi kata-kata. Ada tujuh jenis ekspansi yang dilakukan: ekspansi brace, ekspansi tilde, ekspansi parameter dan variabel, substitusi perintah, ekspansi aritmatika, pemisahan kata, dan ekspansi pathname.

    Urutan ekspansi adalah: ekspansi brace; ekspansi tilde, ekspansi parameter dan variabel, ekspansi aritmatika, dan penggantian perintah (dilakukan dengan cara kiri-ke-kanan); pemisahan kata; dan perluasan pathname.

Pada dasarnya Bash melakukan substitusi variabel terlebih dahulu, sehingga yang $1pertama diganti dengan nilainya. Hanya kemudian melakukan ekspansi aritmatika, yang hanya melihat konstanta yang tepat.

db48x
sumber
Ini sepertinya tidak perlu; OP mengatakan, "Saya mengerti itu $1adalah input."
Scott
8
+1 karena memahami urutan ekspansi sangat berguna untuk memahami banyak ekspresi Bash yang berbeda.
Anthony G - keadilan untuk Monica
1
Ini bisa menjadi komentar untuk jawaban Ipor.
chepner
1
@ chepner Cobalah untuk memeras blokquote yang diformat dengan baik ke dalam komentar :-)
Alexander
1
"Perhatikan bahwa parameter $1diperluas untuk menghasilkan konstanta integer sebelum ekspresi aritmatika dievaluasi. Lihat gnu.org/software/bash/manual/bash.txt , bagian 3.5"
chepner