¿Qué hace exactamente echo $ ((2 # $ 1)) exactamente?

53

El siguiente script bash muestra un número decimal cuando se le da un número binario.

echo $((2#$1))

¿Por qué exactamente?

Entiendo que $1es la entrada. Tal vez 2es la base (binario). Pero no puedo entender la sintaxis utilizada.

NanoPish
fuente

Respuestas:

72

hombre 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
fuente
66
-1 para explicación CERO.
Max Ried
27
Está bastante bien explicado, creo
NanoPish
19
Responder una pregunta por completo, incluso si "solo" curando la documentación existente, no merece -1 para mí. En particular, si esa documentación es la página de manual de bash.
YoungFrog el
31
man bash | wcindica que la página del manual [GNU bash, versión 3.2.57] tiene 4890 líneas, 37094 palabras , 329778 caracteres. Esta respuesta lo reduce a solo 7 líneas, 176 palabras , 1115 caracteres que son relevantes. Creo que esa respuesta merece tu voto positivo. (como este comentario ;-)
Bruno Bronosky
77
@MaxRied: -1 a tu comentario por buscar pelusa innecesaria
Mehrdad
30

Del Doc en: https://tiswww.case.edu/php/chet/bash/bashref.html#Shell-Arithmetic

Las constantes con un 0 inicial se interpretan como números octales. Un '0x' o '0X' inicial denota hexadecimal. De lo contrario, los números toman la forma [base #] n, donde la base opcional es un número decimal entre 2 y 64 que representa la base aritmética, yn es un número en esa base. Si se omite la base #, se usa la base 10. Al especificar n, los dígitos mayores que 9 están representados por las letras minúsculas, las letras mayúsculas, '@' y '_', en ese orden. Si la base es menor o igual a 36, ​​las letras minúsculas y mayúsculas se pueden usar indistintamente para representar números entre 10 y 35.

Así echo $((16#FF))salidas 255y echo $((2#0110))salidas6

su breve
fuente
25

La respuesta de Ipor es excelente pero muy levemente incompleta. La parte citada de la página de manual de bash establece que la sintaxis solo funciona para constantes y no es una constante. ¡Deberías preguntarte cómo funciona esto realmente ![base#]n2#$1

EXPANSIÓN

    La expansión se realiza en la línea de comando después de que se ha dividido en palabras. Se realizan siete tipos de expansión: expansión de llaves, expansión de tilde, expansión de parámetros y variables, sustitución de comandos, expansión aritmética, división de palabras y expansión de nombre de ruta.

    El orden de las expansiones es: expansión de llaves; expansión de tilde, expansión de parámetros y variables, expansión aritmética y sustitución de comandos (hecho de izquierda a derecha); división de palabras; y expansión de nombre de ruta.

Básicamente, Bash está haciendo una sustitución de variables primero, por lo que $1primero se reemplaza por su valor. Solo entonces realiza la expansión aritmética, que solo ve una constante adecuada.

db48x
fuente
Esto parece innecesario; el OP dice: "Entiendo que esa $1es la entrada".
Scott
8
+1 porque comprender el orden de expansión es muy útil para dar sentido a muchas expresiones Bash diferentes.
Anthony G - justicia para Monica
1
Esto podría haber sido simplemente un comentario a la respuesta de Ipor.
chepner
1
@chepner Intente exprimir esa cita en bloque bien formateada en un comentario :-)
Alexander
1
"Tenga en cuenta que el parámetro $1se expande para producir una constante entera antes de evaluar la expresión aritmética. Consulte gnu.org/software/bash/manual/bash.txt , sección 3.5"
chepner