Скажем, я создал следующие переменные:
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_VARtypedef и в функции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.
Эта страница содержит подробное руководство по вводу переменных в 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).