53

The following bash script displays a decimal number when given binary number.

echo $((2#$1))

Why exactly ?

I understand that $1 is the input. Maybe 2 is the base (binary). But I can't understand the syntax used.

72

man 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.
  • 66
    -1 for ZERO explanation. – Max Ried Jan 3 '17 at 8:07
  • 27
    It is pretty well explained I think – NanoPish Jan 3 '17 at 9:19
  • 19
    Fully answering a question, even if "only" by curating existing documentation, does not deserve -1 for me. In particular if that documentation is the manpage of bash. – YoungFrog Jan 3 '17 at 10:06
  • 31
    man bash | wc indicates the [GNU bash, version 3.2.57] man page to be 4890 lines, 37094 words, 329778 characters. This answer strips that down to only the 7 lines, 176 words, 1115 characters that are relevant. I think that answer deserves your upvote. (as does this comment ;-) – Bruno Bronosky Jan 3 '17 at 17:25
  • 7
    @MaxRied: -1 to your comment for seeking unnecessary fluff – Mehrdad Jan 4 '17 at 6:54
30

From the Doc at: https://tiswww.case.edu/php/chet/bash/bashref.html#Shell-Arithmetic

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 represent numbers between 10 and 35.

So echo $((16#FF)) outputs 255 and echo $((2#0110)) outputs 6

25

Ipor's answer is excellent but very slightly incomplete. The quoted part of the bash man page states that the [base#]n syntax works only for constants, and 2#$1 is not a constant. You should be asking how this really works!

EXPANSION

    Expansion is performed on the command line after it has been split into words.  There are seven kinds of expansion performed: brace expansion, tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, word splitting, and pathname expansion.

    The order of expansions is: brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion); word splitting; and pathname expansion.

Basically Bash is doing variable substitution first, so that the $1 is first replaced with its value. Only then does it do arithmetic expansion, which sees only a proper constant.

  • This seems unnecessary; the OP says, "I understand that $1 is the input." – Scott Jan 3 '17 at 16:20
  • 8
    +1 because understanding the order of expansion is very useful for making sense of many different Bash expressions. – Anthony G - justice for Monica Jan 3 '17 at 17:20
  • 1
    This could have simply been a comment to Ipor's answer. – chepner Jan 4 '17 at 2:48
  • 1
    @chepner Please try to squeeze that well-formatted blockquote into a comment :-) – Alexander Jan 4 '17 at 11:37
  • 1
    "Note that the parameter $1 is expanded to produce an integer constant before the arithmetic expression is evaluated. See gnu.org/software/bash/manual/bash.txt, section 3.5" – chepner Jan 4 '17 at 13:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.