Co dokładnie robi echo $ ((2 # $ 1))?

53

Poniższy skrypt bash wyświetla liczbę dziesiętną po podaniu liczby binarnej.

echo $((2#$1))

Dlaczego dokładnie

Rozumiem, że $1to jest wkład. Może 2jest bazą (binarną). Ale nie rozumiem zastosowanej składni.

NanoPish
źródło

Odpowiedzi:

72

uderzenie człowieka

   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
źródło
66
-1 dla wyjaśnienia ZERO.
Max Ried
27
Myślę, że jest to dość dobrze wyjaśnione
NanoPish,
19
Pełne udzielenie odpowiedzi na pytanie, nawet jeśli „tylko” poprzez wybór istniejącej dokumentacji, nie zasługuje na -1 dla mnie. W szczególności, jeśli dokumentacja ta jest stroną podręcznika użytkownika bash.
YoungFrog,
31
man bash | wcwskazuje stronę podręcznika [GNU bash, wersja 3.2.57] na 4890 linii, 37094 słów , 329778 znaków. Ta odpowiedź usuwa tylko 7 wierszy, 176 słów i 1115 znaków. Myślę, że ta odpowiedź zasługuje na twoją opinię. (podobnie jak ten komentarz ;-)
Bruno Bronosky,
7
@MaxRied: -1 do komentarza za szukanie niepotrzebnego puchu
Mehrdad
30

Z dokumentu pod adresem : https://tiswww.case.edu/php/chet/bash/bashref.html#Shell-Arithmetic

Stałe z wiodącym 0 są interpretowane jako liczby ósemkowe. Wiodące „0x” lub „0X” oznacza liczbę szesnastkową. W przeciwnym razie liczby przyjmują postać [podstawa #] n, gdzie opcjonalna podstawa jest liczbą dziesiętną między 2 a 64 reprezentującą podstawę arytmetyczną, a n jest liczbą w tej podstawie. Jeśli baza nr zostanie pominięta, zostanie użyta baza 10. Przy określaniu n cyfry większe niż 9 są reprezentowane przez małe litery, wielkie litery „@” i „_” w tej kolejności. Jeśli podstawa jest mniejsza lub równa 36, ​​małe i wielkie litery mogą być używane zamiennie do reprezentowania liczb od 10 do 35.

Więc echo $((16#FF))wyjścia 255i echo $((2#0110))wyjścia6

itshorty
źródło
25

Odpowiedź Iporta jest doskonała, ale bardzo nieznacznie niepełna. Cytowana część strony podręcznika bash mówi, że składnia działa tylko dla stałych i nie jest stała. Powinieneś zapytać, jak to naprawdę działa![base#]n2#$1

EKSPANSJA

    Rozwinięcie jest wykonywane w wierszu poleceń po podzieleniu go na słowa. Istnieje siedem rodzajów interpretacji: interpretacja nawiasów, interpretacja tyldy, interpretacja parametrów i zmiennych, podstawianie poleceń, interpretacja arytmetyczna, dzielenie słów i interpretacja nazw ścieżek.

    Kolejność rozszerzeń jest następująca: nawias klamrowy; interpretacja tyldy, interpretacja parametrów i zmiennych, interpretacja arytmetyczna i podstawianie poleceń (wykonywane od lewej do prawej); dzielenie słów; i rozszerzenie nazwy ścieżki.

Zasadniczo Bash najpierw wykonuje podstawienie zmiennych, aby $1najpierw zastąpić je swoją wartością. Dopiero wtedy dokonuje ekspansji arytmetycznej, która widzi tylko odpowiednią stałą.

db48x
źródło
To wydaje się niepotrzebne; OP mówi: „Rozumiem, że $1to jest wkład”.
Scott
8
+1, ponieważ zrozumienie kolejności rozwijania jest bardzo przydatne do zrozumienia wielu różnych wyrażeń Bash.
Anthony G - sprawiedliwość dla Moniki
1
To mógł być po prostu komentarz do odpowiedzi Iporta.
chepner
1
@chepner Spróbuj wycisnąć dobrze sformatowany cytat blokowy w komentarz :-)
Alexander
1
„Zauważ, że parametr $1jest rozszerzany, aby uzyskać stałą całkowitą przed obliczeniem wyrażenia arytmetycznego. Zobacz gnu.org/software/bash/manual/bash.txt , sekcja 3.5”
chepner