Po prostu z braku zainteresowania, dlaczego miałoby to mieć znaczenie? Naprawdę nie dbam o to, czy były przechowywane jako tekst suahili, o ile nie wpłynęło to na funkcjonalność języka (wpływ na wydajność może być problemem, ale jeśli to ważne, są lepszymi narzędziami w twoim arsenale niż bash).
2
@paxdiablo To nie ma znaczenia, po prostu pytam z ciekawości, ponieważ wszystkie inne języki programowania / skryptów, które znam (na przykład: Java, C ++, JavaScript, PHP itp.) mają unikalną reprezentację pamięci dla każdego typu danych , dlatego interesujące jest zobaczenie języka skryptowego, który ma tylko jedną reprezentację pamięci dla wszystkich typów danych.
user268325
Odpowiedzi:
16
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.
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.
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:
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ć.
Myślę, że celem pytania była raczej reprezentacja niż lokalizacja
bu5hman
2
Chodzi mi o to, że nie możesz znać przedstawienia, ponieważ nie możesz go zaobserwować. Jest to więc nieistotne i może się zmienić bez Twojej uwagi. Po prostu niemożliwe jest określenie, jaką reprezentację może wybrać Bash. Możesz zagłębić się w kod źródłowy implementacji i sprawdzić, jaką reprezentację wybierze, ale może zmienić reprezentację jutro w następnej wersji łaty i nie będzie sposobu, aby wiedzieć.
Jörg W Mittag
Zmienne Schroedingersa? Zgadzam się z tobą zasadniczo, że podstawowa reprezentacja jest nieistotna (patrz moja odpowiedź), ale używając bash skutecznie „kodujemy interfejs”, a reprezentacja na interfejsie jest rygorystyczna.
bu5hman
2
Tak, ale pytanie nie dotyczy reprezentacji na granicy interfejsu, ale konkretnie tego, w jaki sposób są one „przechowywane w pamięci”. I na to pytanie odpowiedziałbym: nie wiemy, nie możemy i nie powinniśmy wiedzieć.
Jörg W Mittag
Które parafrazują ostatnią linijkę mojego własnego posta ..... jak już powiedziałem, zgadzamy się ...... i biorąc pod uwagę przedstawiciela PO i charakter pytania, myślę, że otrzymają rozsądne oceny za pracę domową, ktokolwiek dostaje cytat ;-).
bash
).Odpowiedzi:
Zmienne Bash są bez typu .
Jak mówi inna odpowiedź , istnieje pewna słaba forma pisania na klawiaturze
declare
.Zobacz przykład:
Bibliografia:
źródło
Bash zasadniczo ma proste zmienne skalarne, tablice i tablice asocjacyjne. Ponadto,
declare
wbudowane 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_VAR
typedef 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żywanego
union _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.źródło
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
declare
jako ciągi z atrybutów , które kontrolują w jaki sposób, że zmienna ma być rozszerzony przezdeclare
podczas przechowywania.I oczywiście
Coda tego polega na tym, że nawet jeśli
declare
ma wewnętrzną reprezentację, która zmienia się wraz z flagami atrybutów, ciągi są wszystkim, co bash widzi lub chce zobaczyć.źródło
Ta strona zawiera obszerny przewodnik na temat pisania zmiennych w Bash. Ta sekcja zawiera więcej informacji na temat
declare
wbudowanego polecenia. Ten fragment kodu z tego linku może być interesujący:Oto
man
strona dladeclare
.źródło
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ć.
źródło