55

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.

NanoPish
  • 858
  • if you understood that $1 was a positional parameter then you should have simplified your question and done just echo $((2#0110)) as you did and got '6'. Then you ask if 2 was the base. Well obviously. And it's not hard to test that. It's no coincidence that echo $((2#0111)) is 7. and $((2#1000))` is 8. You got it for one binary number. So given that, then yeah you got it anyway , obviously – barlop Dec 16 '20 at 17:43
  • @barlop I recently edited the question to add the echo $((2#0110)) = 6 part, because I noticed there was no direct example with output in my question and in the answers – NanoPish Dec 17 '20 at 10:54
  • Kind of makes a nonsense of the question ('cos if a questioner knew that then they'd know the answer). Though as you know an example is good. It's one of those things where if you'd been careful about asking the question properly in the first place before posting it, so before clicking "submit/post", then you would have ended up solving it yourself easily. Sometimes I start asking a question and i've typed it and refined it but I solve it in the process of asking a good question, so nothing to ask. Other times I solve the question but it's a good question so I post both Q and A. – barlop Dec 17 '20 at 11:06
  • this one wasn't a well written question, because you just posted it without doing any troubleshooting – barlop Dec 17 '20 at 11:08
  • @barlop well thank you for your opinion, it is very interesting. other users seem to have had another one – NanoPish Dec 17 '20 at 11:20
  • @barlop your first remark is right tho, I added the example to the accepted answer instead of my original question – NanoPish Dec 17 '20 at 11:23

3 Answers3

76

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.
Ipor Sircer
  • 4,103
  • 1
  • 16
  • 19
  • 66
    -1 for ZERO explanation. – bot47 Jan 03 '17 at 08:07
  • 28
    It is pretty well explained I think – NanoPish Jan 03 '17 at 09: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 03 '17 at 10:06
  • 4
    I didn't vote, but, IMHO, quoting the explanation of the echo command was unnecessary. – Scott - Слава Україні Jan 03 '17 at 16:19
  • 33
    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 03 '17 at 17:25
  • 2
    @BrunoBronosky dunno you, but my pager have search on the / key. – Braiam Jan 03 '17 at 20:39
  • 2
    @Braiam, yes and /2# gives 0 results, but seriously this is not a place for debate and 1337ism. My comment was intended to encourage community not exacerbate division. There is an important cultural difference between SE and Reddit/4chan/etc. – Bruno Bronosky Jan 03 '17 at 20:46
  • 1
    @Braiam - I gave up on the pager a long time ago. I do a man bash > bashman.txt, make it read only and throw it into kate. I just have to remember to get a new version every so often. It's nice to have a script on one tab and the manual on another. I do the same thing for awk and yad. – Joe Jan 04 '17 at 03:46
  • 7
    @MaxRied: -1 to your comment for seeking unnecessary fluff – user541686 Jan 04 '17 at 06:54
  • 1
    @Joe You can do man bash | kate -i if you're not worried about the filename. Or man bash | gedit - for folk who use gedit. Note the dash on the end. – seumasmac Jan 04 '17 at 12:58
  • @seumasmac - I was wondering what that -i option was good for. Thanks. – Joe Jan 04 '17 at 20:46
  • 1
    @MaxRied What nonsense. You're the one who's rigidly copying something without any flexibility here. In general those answers which just copy things are bad because they confuse the readers since they're not directly relevant/applicable to the question. But here the relevant explanations are all here. It's just that they come from the source instead of being rephrased. If something is already clear enough, why would you rephrase? It would just be an absolute waste of effort anyways. – xji Jan 05 '17 at 20:28
31

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

itshorty
  • 410
26

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.

db48x
  • 574