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.

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.

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


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.


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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.