Скажіть, я створив такі змінні:
s=John
i=12345
f=3.14
Чи всі ці змінні зберігаються в пам'яті як рядкові, чи bash
є інші типи даних?
Скажіть, я створив такі змінні:
s=John
i=12345
f=3.14
Чи всі ці змінні зберігаються в пам'яті як рядкові, чи bash
є інші типи даних?
Відповіді:
Змінні Bash не типізовані .
На відміну від багатьох інших мов програмування, Bash не відокремлює свої змінні за "типом". По суті, Bash змінні - це символьні рядки, але, залежно від контексту, Bash дозволяє арифметичні операції та порівняння змінних. Визначальним фактором є те, чи містить значення змінної лише цифри.
Як говорить інша відповідь , існує якась слабка форма набору тексту declare
.
Це дуже слабка форма набору тексту [1], доступна в певних мовах програмування.
Дивіться приклад:
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 по суті має прості скалярні змінні, масиви та асоціативні масиви. Крім того, скаляри можуть бути позначені цілими числами з declare
вбудованим . З точки зору користувача програміста сценарію / оболонки, струнні змінні виступають як рядки, цілі змінні діють як цілі числа, і масиви відповідно до їх типу. Внутрішня реалізація не дуже актуальна.
Але, якщо ми хочемо знати, як дані насправді зберігаються в пам'яті, ми повинні вивчити вихідний код, щоб побачити, що насправді робить програма.
У Bash 4.4 скаляри зберігаються як рядки незалежно від цілого тегу. Це видно у визначенні struct variable
/ SHELL_VAR
typedef та у функціїmake_variable_value
, яка явно переводить цілі числа до рядків для зберігання.
Масиви зберігаються у тому, що виглядає як пов'язаний список ( array.h
), а асоціативні масиви - хеш-таблиці. Значення всередині них знову зберігаються як рядки. Вибір пов'язаного списку для масивів може здатися дивним, але оскільки масиви можуть бути рідкими, а індекси можуть бути довільними числами незалежно від того, скільки елементів містить масив, вибір дизайну трохи простіше зрозуміти.
Однак код також містить визначення невикористаногоunion _value
з полями для цілих чисел, чисел з плаваючою комою, а також значень рядків. У коментарі це позначено як "на майбутнє", тому можливо, що деяка майбутня версія Bash зберігатиме різні типи скалярів у рідних формах.
За все життя я не можу знайти це ніде сказане так багато слів, але це я так розумію.
Bash - інтерпретатор, а не компілятор і представляє всі змінні як рядки. Звідси всі зусилля та акценти, що пов'язані з різними розширеннями.
Bash передає передає всі імена змінних в declare
вигляді рядків з атрибутами , які контролюють , як ця змінна повинна бути розширена шляхом 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" )
І звичайно
declare -ia finale[1]=9+16
declare -p finale
declare -ai finale=([1]="25")
Кода до цього полягає в тому, що навіть якщо declare
є внутрішнє представлення, яке змінюється прапорами атрибутів, рядки - це все, що баш бачить або хоче бачити.
На цій сторінці є вичерпний посібник із введення змінних у Bash. У цьому розділі є додаткова інформація про declare
вбудовану команду. Цей фрагмент коду з цього посилання може зацікавити:
[bob in ~] declare -i VARIABLE=12
[bob in ~] VARIABLE=string
[bob in ~] echo $VARIABLE
0
[bob in ~] declare -p VARIABLE
declare -i VARIABLE="0"
Це не має значення.
Єдиний спосіб взаємодії зі змінними Bash - це через Bash, тому неможливо помітити будь-яку різницю щодо того, як змінні зберігаються в пам'яті, тому що ви ніколи не можете отримати доступ до них через пам'ять безпосередньо , вам завжди потрібно запитати у Bash їх значення, і Bash може потім перевести їх в який би шлях він хоче виглядати , як якщо б вони були збережені в будь-якому певним чином.
Насправді, вони не можуть навіть бути збережені в пам'яті у всіх . Я не знаю, наскільки розумні загальні реалізації Bash, але принаймні в простих випадках можна визначити, чи буде використовуватися змінна та / або чи буде вона модифікована, і повністю її оптимізувати чи вбудовувати.
bash
).