Powiedzmy, że utworzyłem następujące zmienne:
s=John
i=12345
f=3.14
Czy wszystkie te zmienne są przechowywane w pamięci jako ciąg, czy też bashmają inne typy danych?
Powiedzmy, że utworzyłem następujące zmienne:
s=John
i=12345
f=3.14
Czy wszystkie te zmienne są przechowywane w pamięci jako ciąg, czy też bashmają inne typy danych?
Odpowiedzi:
Zmienne Bash są bez typu .
W przeciwieństwie do wielu innych języków programowania, Bash nie segreguje swoich zmiennych według „typu”. Zasadniczo zmienne Bash są ciągami znaków, ale w zależności od kontekstu Bash pozwala na operacje arytmetyczne i porównania zmiennych. Czynnikiem decydującym jest to, czy wartość zmiennej zawiera tylko cyfry.
Jak mówi inna odpowiedź , istnieje pewna słaba forma pisania na klawiaturze declare.
Jest to bardzo słaba forma pisania [1] dostępna w niektórych językach programowania.
Zobacz przykład:
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.
Bibliografia:
Bash zasadniczo ma proste zmienne skalarne, tablice i tablice asocjacyjne. Ponadto, declarewbudowane skalary mogą być oznaczone jako liczby całkowite . Z punktu widzenia programisty / użytkownika powłoki zmienne łańcuchowe działają jak łańcuchy, zmienne całkowite działają jako liczby całkowite, a tablice odpowiednio do ich typu. Wewnętrzne wdrożenie nie jest zbyt istotne.
Ale jeśli chcemy wiedzieć, jak dane są faktycznie przechowywane w pamięci, musimy zbadać kod źródłowy, aby zobaczyć, co faktycznie robi program.
W Bash 4.4 skalary są przechowywane jako ciągi, niezależnie od znacznika liczby całkowitej. Jest to widoczne w definicji struct variable/ SHELL_VARtypedef oraz w funkcjimake_variable_value , która jawnie tłumaczy liczby całkowite na ciągi do przechowywania.
Tablice są przechowywane na czymś, co wygląda na listę połączoną ( array.h), a tablice asocjacyjne jako tabele skrótów. Wartości w nich zapisane są ponownie jako ciągi znaków. Wybór połączonej listy dla tablic może wydawać się dziwny, ale ponieważ tablice mogą być rzadkie, a indeksy mogą być dowolnymi liczbami, niezależnie od tego, ile elementów zawiera tablica, wybór projektu jest nieco łatwiejszy do zrozumienia.
Jednak kod zawiera również definicję nieużywanegounion _value , z polami na liczby całkowite, liczby zmiennoprzecinkowe, a także wartości ciągu. Jest oznaczony w komentarzu jako „na przyszłość”, więc możliwe jest, że niektóre przyszłe wersje Bash będą przechowywać różne rodzaje skalarów w ich rodzimych formach.
W moim życiu nie mogę tego znaleźć w wielu słowach, ale tak to rozumiem.
Bash jest interpretatorem, a nie kompilatorem i reprezentuje wszystkie zmienne jako ciągi znaków. Stąd cały wysiłek i nacisk związany z różnego rodzaju ekspansjami.
Bash przechodzi przechodzi wszystkie nazwanych zmiennych declarejako ciągi z atrybutów , które kontrolują w jaki sposób, że zmienna ma być rozszerzony przez declarepodczas przechowywania.
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" )
I oczywiście
declare -ia finale[1]=9+16
declare -p finale
declare -ai finale=([1]="25")
Coda tego polega na tym, że nawet jeśli declarema wewnętrzną reprezentację, która zmienia się wraz z flagami atrybutów, ciągi są wszystkim, co bash widzi lub chce zobaczyć.
Ta strona zawiera obszerny przewodnik na temat pisania zmiennych w Bash. Ta sekcja zawiera więcej informacji na temat declarewbudowanego polecenia. Ten fragment kodu z tego linku może być interesujący:
[bob in ~] declare -i VARIABLE=12
[bob in ~] VARIABLE=string
[bob in ~] echo $VARIABLE
0
[bob in ~] declare -p VARIABLE
declare -i VARIABLE="0"
To nie ma znaczenia.
Jedynym sposobem interakcji ze zmiennymi Bash jest użycie Bash, więc nie można zauważyć żadnej różnicy, w jaki sposób zmienne są przechowywane w pamięci, ponieważ nigdy nie można uzyskać do nich dostępu bezpośrednio przez pamięć , zawsze należy poprosić Bash o ich wartość i atakujących może następnie przełożyć je w jakikolwiek sposób chce wyglądać tak, jakby był przechowywany w żaden szczególny sposób.
W rzeczywistości, może nawet nie być przechowywane w pamięci w ogóle . Nie wiem, jak sprytne są popularne implementacje Basha, ale przynajmniej w prostych przypadkach można przynajmniej ustalić, czy zmienna zostanie użyta i / lub czy zostanie zmodyfikowana, i zoptymalizować ją całkowicie lub wbudować.
bash).