53

Следующий скрипт bash отображает десятичное число, если задано двоичное число.

echo $((2#$1))

Почему именно?

Я понимаю, что $1 - это вход. Может быть, 2 является основанием (двоичным). Но я не могу понять используемый синтаксис.

3 ответа3

73

человек баш

   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.
30

Из документа по адресу: https://tiswww.case.edu/php/chet/bash/bashref.html#Shell-Arithmetic.

Константы с ведущим 0 интерпретируются как восьмеричные числа. Ведущий '0x' или '0X' обозначает шестнадцатеричное. В противном случае числа принимают форму [base #] n, где необязательное основание - это десятичное число от 2 до 64, представляющее арифметическое основание, а n - это число в этом основании. Если base # опущен, используется base 10. При указании n цифры больше 9 представляются строчными буквами, заглавными буквами '@' и '_' в указанном порядке. Если основание меньше или равно 36, строчные и прописные буквы могут использоваться взаимозаменяемо для представления чисел от 10 до 35.

Поэтому echo $((16#FF)) выводит 255 а echo $((2#0110)) выводит 6

25

Ответ Ипора отличный, но немного неполный. В цитируемой части справочной страницы bash говорится, что синтаксис [base#]n работает только для констант, а 2#$1 не является константой. Вы должны спросить, как это действительно работает!

РАСШИРЕНИЕ

    Расширение выполняется в командной строке после того, как оно было разбито на слова.  Существует семь видов выполняемых расширений: расширение фигурных скобок, расширение тильды, расширение параметров и переменных, подстановка команд, арифметическое расширение, разбиение слов и расширение имени пути.

    Порядок разложений: раскладывание скобок; раскрытие тильды, расширение параметров и переменных, арифметическое расширение и подстановка команд (выполняется слева направо); расщепление слов; и расширение пути.

По сути, Bash сначала выполняет подстановку переменных, поэтому сначала $1 заменяется его значением. Только тогда он делает арифметическое расширение, которое видит только правильную константу.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .