Werden alle Variablen als Zeichenfolge in der Bash gespeichert?


13

Angenommen, ich habe die folgenden Variablen erstellt:

s=John
i=12345
f=3.14

Werden alle diese Variablen als Zeichenfolge gespeichert oder bashhaben sie andere Datentypen?


1
Nur aus Interesse, warum sollte es wichtig sein? Es ist mir wirklich egal, ob sie als Suaheli-Text gespeichert werden, solange dies die Funktionalität der Sprache nicht beeinträchtigt (Leistungseinbußen sind möglicherweise ein Problem, aber wenn das wichtig ist, sind sie bessere Werkzeuge in Ihrem Arsenal als bash).

2
@paxdiablo Egal, ich frage nur aus Neugier, da alle anderen mir bekannten Programmier- / Skriptsprachen (z. B. Java, C ++, JavaScript, PHP usw.) für jeden Datentyp eine eindeutige Speicherdarstellung haben Daher ist es interessant, eine Skriptsprache zu sehen, die nur eine Speicherdarstellung für alle Datentypen enthält.
user268325

Antworten:


16

Bash-Variablen sind untypisiert .

Im Gegensatz zu vielen anderen Programmiersprachen trennt Bash seine Variablen nicht nach "Typ". Bash-Variablen sind im Wesentlichen Zeichenfolgen, aber je nach Kontext ermöglicht Bash arithmetische Operationen und Vergleiche mit Variablen. Ausschlaggebend ist, ob der Wert einer Variablen nur Ziffern enthält.

Wie eine andere Antwort sagt , gibt es eine Art schwache Form des Tippens mit declare.

Dies ist eine sehr schwache Form der Typisierung [1], die in bestimmten Programmiersprachen verfügbar ist.

Siehe ein Beispiel:

declare -i number
# The script will treat subsequent occurrences of "number" as an integer.     

number=3
echo "Number = $number"     # Number = 3

number=three
echo "Number = $number"     # Number = 0
# Tries to evaluate the string "three" as an integer.

Verweise:


13

Bash besteht im Wesentlichen aus einfachen skalaren Variablen, Arrays und assoziativen Arrays. Darüber hinaus können Skalare als Ganzzahlen mit dem declareeingebauten Tag versehen werden . Aus Sicht des Skriptprogrammierers / Shell-Benutzers fungieren Zeichenfolgenvariablen als Zeichenfolgen, Ganzzahlvariablen als Ganzzahlen und Arrays entsprechend ihrem Typ. Die interne Implementierung ist nicht sehr relevant.


Wenn wir jedoch wissen möchten, wie die Daten tatsächlich im Speicher gespeichert sind, müssen wir den Quellcode untersuchen, um festzustellen, was das Programm tatsächlich tut.

In Bash 4.4 werden Skalare unabhängig vom Integer-Tag als Zeichenfolgen gespeichert. Dies ist in der Definition von struct variable/ the SHELL_VARtypedef und in der Funktionmake_variable_value sichtbar , die Ganzzahlen explizit in Zeichenfolgen für die Speicherung übersetzt.

Arrays werden in einer scheinbar verknüpften Liste ( array.h) und assoziative Arrays als Hash-Tabellen gespeichert . Die darin enthaltenen Werte werden wieder als Zeichenfolgen gespeichert. Die Auswahl einer verknüpften Liste für Arrays mag seltsam erscheinen, aber da die Arrays spärlich sein können und die Indizes beliebige Zahlen sein können, unabhängig davon, wie wenige Elemente das Array enthält, ist die Auswahl des Entwurfs etwas einfacher zu verstehen.

Der Code enthält jedoch auch eine Definition für die nicht verwendetenunion _value Felder für Ganzzahlen, Gleitkommazahlen sowie Zeichenfolgenwerte. Es ist in einem Kommentar als "für die Zukunft" markiert, daher ist es möglich, dass eine zukünftige Version von Bash verschiedene Arten von Skalaren in ihren ursprünglichen Formen speichert.


1

Für mein Leben kann ich das nirgends in so vielen Worten finden, aber so verstehe ich es.

Bash ist ein Interpreter, kein Compiler und repräsentiert alle Variablen als Strings. Daher all der Aufwand und die Betonung, die mit den Erweiterungen verschiedener Art einhergehen.

Bash-Übergaben übergeben alle benannten Variablen declareals Zeichenfolgen mit Attributen , die steuern, wie diese Variable beim Speichern erweitert werden soll declare.

banana=yellow              #no call to declare
declare -p banana
declare -- banana="yellow" #but declare was invoked with --

declare -i test=a          #arithmetic expansion to null/zero
declare -p test
declare -i test="0"

declare -i test2=5+4       #successful arithmetic expansion
declare -p test2
declare -i test2="9"

declare -i float=99.6      #arithmetical expansion fails due to syntax
bash: declare: 99.6: syntax error: invalid arithmetic operator (error token is ".6")

nofloat=99.9
declare -p nofloat
declare -- nofloat"99.6"   #Success because arithmetical expansion not invoked

declare -a a               #variable is marked as a placeholder to receive an array
declare -p a
declare -a a

a[3]=99                    #array elements are appended
a[4]=99
declare -p a
declare -a a=([3]="99" [4]="99") 

declare -A newmap          #same as -a but names instead of numbers
newmap[name]="A Bloke"
newmap[designation]=CFO
newmap[company]="My Company"
declare -p newmap
declare -A newmap=([company]="My Company" [name]="A Bloke" [designation]="CFO" )

Und natürlich

declare -ia finale[1]=9+16
declare -p finale
declare -ai finale=([1]="25")

Die Coda dazu ist, dass selbst wenn declaresich eine interne Darstellung mit den Attributflags ändert, Strings alles sind, was bash sieht oder sehen will.



0

Es ist irrelevant.

Der einzige Weg , mit Bash Variablen zu interagieren , ist durch Bash, so ist es unmöglich für Sie einen Unterschied bemerken , wie die Variablen im Speicher abgelegt werden, denn man kann nie direkt , sie durch den Speicher zugreifen , können Sie immer heftiger Schlag müssen fragen , für ihre Wert und Bash können sie dann in welcher Weise auch immer übersetzen will es aussehen , als ob sie hatte in einer bestimmten Art und Weise gespeichert.

In der Tat, sie nicht einmal im Speicher gespeichert werden kann überhaupt . Ich weiß nicht, wie clever die gängigen Implementierungen von Bash sind, aber es ist zumindest in einfachen Fällen möglich, zu bestimmen, ob eine Variable verwendet und / oder geändert wird, und sie vollständig zu optimieren oder zu integrieren.


Ich denke, der Punkt der Frage war eher die Darstellung als der Ort
bu5hman

2
Mein Punkt ist, dass Sie die Darstellung nicht kennen, weil Sie sie nicht beobachten können. Es ist also irrelevant und kann sich ändern, ohne dass Sie es bemerken. Es ist einfach unmöglich zu sagen, welche Darstellung Bash wählen könnte. Sie könnten sich mit dem Quellcode einer Implementierung befassen und herausfinden, welche Darstellung sie auswählt, aber es könnte morgen in der nächsten Patch-Version die Darstellung ändern, und Sie könnten es nicht wissen.
Jörg W Mittag

Schröders Variablen? Grundsätzlich stimme ich Ihnen zu, dass die zugrunde liegende Darstellung irrelevant ist (siehe meine Antwort), aber bei der Verwendung von bash codieren wir effektiv für eine Schnittstelle, und die Darstellung an der Schnittstelle ist strikt.
Bu5hman

2
Ja, aber es geht nicht um die Darstellung an der Schnittstellengrenze, sondern speziell darum, wie sie "im Speicher gespeichert" werden. Und auf diese Frage würde ich antworten: Wir wissen es nicht, können es nicht und sollten es nicht wissen.
Jörg W Mittag

Welches die letzte Zeile meines eigenen Beitrags paraphrasiert ..... wie gesagt, wir sind uns einig ...... und geben OPs rep und die Art der Frage, ich denke, sie werden vernünftige Noten für ihre Hausaufgaben bekommen, wer auch immer wird zitiert ;-).
Bu5hman
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.