O que echo $ ((2 # $ 1)) faz exatamente?

53

O script bash a seguir exibe um número decimal quando determinado número binário.

echo $((2#$1))

Por que exatamente?

Eu entendo que $1é a entrada. Talvez 2seja a base (binária). Mas não consigo entender a sintaxe usada.

NanoPish
fonte

Respostas:

72

festança do homem

   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
fonte
66
-1 para explicação ZERO.
Max Ried
27
É muito é bem explicado eu acho
NanoPish
19
Responder totalmente a uma pergunta, mesmo que "apenas" com a curadoria da documentação existente, não merece -1 para mim. Em particular, se essa documentação for a página de manual do bash.
YoungFrog
31
man bash | wcindica que a página do manual [GNU bash, versão 3.2.57] tem 4890 linhas, 37094 palavras , 329778 caracteres. Essa resposta reduz apenas as 7 linhas, 176 palavras e 1115 caracteres relevantes. Eu acho que essa resposta merece seu voto positivo. (como faz este comentário ;-)
de Bruno Bronosky
7
@MaxRied: -1 a seu comentário para buscar fluff desnecessário
Mehrdad
30

Do documento em: https://tiswww.case.edu/php/chet/bash/bashref.html#Shell-Arithmetic

As constantes com um 0 inicial são interpretadas como números octais. Um '0x' ou '0X' inicial indica hexadecimal. Caso contrário, os números assumem a forma [base #] n, onde a base opcional é um número decimal entre 2 e 64, representando a base aritmética, e n é um número nessa base. Se o número da base for omitido, a base 10 será usada. Ao especificar n, os dígitos maiores que 9 são representados pelas letras minúsculas, maiúsculas '@' e '_', nessa ordem. Se a base for menor ou igual a 36, ​​as letras minúsculas e maiúsculas podem ser usadas de forma intercambiável para representar números entre 10 e 35.

Então echo $((16#FF))saídas 255e echo $((2#0110))saídas6

itshorty
fonte
25

A resposta de Ipor é excelente, mas um pouco incompleta. A parte citada da página de manual do bash afirma que a sintaxe funciona apenas para constantes e não é uma constante. Você deve estar se perguntando como isso realmente funciona![base#]n2#$1

EXPANSÃO

    A expansão é realizada na linha de comando após ter sido dividida em palavras. Existem sete tipos de expansão executados: expansão de chaves, expansão de til, expansão de parâmetro e variável, substituição de comando, expansão aritmética, divisão de palavras e expansão de nome de caminho.

    A ordem das expansões é: expansão de chaves; expansão de til, expansão de parâmetro e variável, expansão aritmética e substituição de comando (feita da esquerda para a direita); divisão de palavras; e expansão do nome do caminho.

Basicamente, o Bash faz a substituição de variáveis ​​primeiro, para que $1seja substituído primeiro pelo seu valor. Só então ele faz a expansão aritmética, que vê apenas uma constante adequada.

db48x
fonte
Isso parece desnecessário; o OP diz: "Entendo que essa $1é a entrada".
Scott
8
+1 porque entender a ordem da expansão é muito útil para entender muitas expressões diferentes do Bash.
Anthony G - justiça para Monica
11
Isso poderia ter sido simplesmente um comentário à resposta de Ipor.
chepner
11
@chepner Por favor tente espremer que formatado-bem blockquote em um comentário :-)
Alexander
11
"Observe que o parâmetro $1é expandido para produzir uma constante inteira antes que a expressão aritmética seja avaliada. Consulte gnu.org/software/bash/manual/bash.txt , seção 3.5"
chepner