Was genau macht echo $ ((2 # $ 1))?

53

Das folgende Bash-Skript zeigt eine Dezimalzahl an, wenn eine Binärzahl angegeben wird.

echo $((2#$1))

Warum genau?

Ich verstehe, dass $1das der Input ist. Vielleicht 2ist die Basis (binär). Aber ich kann die verwendete Syntax nicht verstehen.

NanoPish
quelle

Antworten:

72

Mann 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
quelle
66
-1 für NULL Erklärung.
Max Ried
27
Ich denke, es ist ziemlich gut erklärt
NanoPish
19
Die vollständige Beantwortung einer Frage, auch wenn "nur" durch Kuratieren der vorhandenen Dokumentation, verdient -1 für mich nicht. Insbesondere, wenn es sich bei dieser Dokumentation um die Manpage von bash handelt.
YoungFrog
31
man bash | wcgibt an, dass die Manpage [GNU bash, Version 3.2.57] 4890 Zeilen, 37094 Wörter , 329778 Zeichen enthält. Diese Antwort zeigt, dass nur die 7 Zeilen, 176 Wörter und 1115 Zeichen relevant sind. Ich denke, diese Antwort verdient Ihre Zustimmung. (Wie auch dieser Kommentar ;-)
Bruno Bronosky
7
@ MaxRied: -1 zu Ihrem Kommentar für die Suche nach unnötigen Flusen
Mehrdad
30

Aus dem Doc unter: https://tiswww.case.edu/php/chet/bash/bashref.html#Shell-Arithmetic

Konstanten mit einer führenden 0 werden als Oktalzahlen interpretiert. Ein führendes "0x" oder "0X" bedeutet hexadezimal. Ansonsten haben Zahlen die Form [base #] n, wobei die optionale Basis eine Dezimalzahl zwischen 2 und 64 ist, die die arithmetische Basis darstellt, und n eine Zahl in dieser Basis ist. Wenn base # weggelassen wird, wird base 10 verwendet. Wenn Sie n angeben, werden die Ziffern größer als 9 durch die Kleinbuchstaben, die Großbuchstaben '@' und '_' in dieser Reihenfolge dargestellt. Wenn base kleiner oder gleich 36 ist, können Klein- und Großbuchstaben austauschbar verwendet werden, um Zahlen zwischen 10 und 35 darzustellen.

Also echo $((16#FF))Ausgänge 255und echo $((2#0110))Ausgänge6

itshorty
quelle
25

Die Antwort von Ipor ist ausgezeichnet, aber sehr leicht unvollständig. Der zitierte Teil der Bash-Manpage besagt, dass die Syntax nur für Konstanten funktioniert und keine Konstante ist. Sie sollten sich fragen, wie das wirklich funktioniert![base#]n2#$1

ERWEITERUNG

    Die Erweiterung wird in der Befehlszeile ausgeführt, nachdem sie in Wörter aufgeteilt wurde. Es werden sieben Arten von Erweiterungen durchgeführt: Klammererweiterung, Tildeerweiterung, Parameter- und Variablenerweiterung, Befehlssubstitution, arithmetische Erweiterung, Wortteilung und Pfadnamenerweiterung.

    Die Reihenfolge der Erweiterungen ist: Klammererweiterung; Tildeerweiterung, Parameter- und Variablenerweiterung, arithmetische Erweiterung und Befehlssubstitution (von links nach rechts); Wortspaltung; und Pfadnamenerweiterung.

Grundsätzlich setzt Bash zuerst Variablen ein, so dass diese $1zuerst durch ihren Wert ersetzt werden. Nur dann führt es eine arithmetische Expansion durch, die nur eine richtige Konstante sieht.

db48x
quelle
Dies scheint unnötig; Das OP sagt: "Ich verstehe, das $1ist der Input."
Scott
8
+1, da das Verstehen der Expansionsreihenfolge sehr nützlich ist, um viele verschiedene Bash-Ausdrücke zu verstehen.
Anthony G - Gerechtigkeit für Monica
1
Dies hätte einfach ein Kommentar zu Ipor's Antwort sein können.
Chepner
1
@chepner Bitte versuchen Sie, dieses gut formatierte Blockzitat in einen Kommentar zu packen :-)
Alexander
1
"Beachten Sie, dass der Parameter $1erweitert wird, um eine Ganzzahlkonstante zu erzeugen, bevor der arithmetische Ausdruck ausgewertet wird. Siehe gnu.org/software/bash/manual/bash.txt , Abschnitt 3.5"
chepner