Просто из интереса, почему это имеет значение? Мне действительно было наплевать, хранятся ли они в виде текста на суахили, если это не влияет на функциональность языка (может быть проблема с производительностью, но, если это важно, они являются лучшими инструментами в вашем арсенале, чем bash).
2
@paxdiablo Это не имеет значения, я просто из любопытства спрашиваю, так как все другие языки программирования / скриптов, которые я знаю (например, Java, C ++, JavaScript, PHP и т. д.), имеют уникальное представление памяти для каждого типа данных. , поэтому интересно увидеть язык сценариев, который имеет только одно представление памяти для всех типов данных.
user268325
Ответы:
16
Переменные 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встроенной функции . С точки зрения программиста скрипта / пользователя оболочки строковые переменные действуют как строки, целочисленные переменные действуют как целые числа, и массивы соответствуют их типу. Внутренняя реализация не очень актуальна.
Но, если мы хотим знать, как данные на самом деле хранятся в памяти, мы должны изучить исходный код, чтобы увидеть, что на самом деле делает программа.
Массивы хранятся в том, что выглядит как связанный список ( 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 через Bash, так что это невозможно для вас , чтобы заметить разницу относительно того , как переменные хранятся в памяти, потому что вы не можете и не получить доступ к ним через память напрямую , вы всегда должны спросить Bash для их значение, и Bash может затем перевести их в какой бы путь он хочет выглядеть , как если бы они были сохранены в любом определенным образом.
На самом деле, они не могут даже быть сохранены в памяти у всех . Я не знаю, насколько умны общие реализации Bash, но, по крайней мере, в простых случаях возможно определить, будет ли использоваться переменная и / или будет ли она изменена, и полностью ее оптимизировать или встроить.
Я думаю, что суть вопроса была в представлении, а не в месте
bu5hman
2
Я хочу сказать, что вы не можете знать представление, потому что вы не можете наблюдать его. Таким образом, это не имеет значения, и это может измениться, даже если вы не заметите. Просто невозможно сказать, какое представление может выбрать Bash. Вы можете вникнуть в исходный код реализации и проверить, какое представление оно выберет, но это может изменить представление завтра в следующем выпуске патча, и у вас не будет возможности узнать об этом.
Йорг Миттаг
Переменные Шредингера? Я согласен с вами в основном в том, что базовое представление не имеет значения (см. Мой ответ), но при использовании bash мы фактически «кодируем интерфейс», и представление в интерфейсе является неровным.
bu5hman
2
Да, но речь идет не о представлении на границе раздела, а конкретно о том , как они «хранятся в памяти». И на этот вопрос я бы ответил: мы не знаем, не можем и не должны знать.
Йорг Миттаг
Который перефразирует последнюю строку моего собственного поста ..... как я уже сказал, мы согласны ...... и учитывая представителя ОП и характер вопроса, я думаю, что они получат разумные оценки за свою домашнюю работу, кто бы ни получает цитату ;-).
bash
).Ответы:
Переменные Bash не типизированы .
Как говорит другой ответ , существует некоторая слабая форма печатания с
declare
.Смотрите пример:
Ссылки:
источник
Bash по существу имеет простые скалярные переменные, массивы и ассоциативные массивы. Кроме того, скаляры могут быть помечены как целые числа с помощью
declare
встроенной функции . С точки зрения программиста скрипта / пользователя оболочки строковые переменные действуют как строки, целочисленные переменные действуют как целые числа, и массивы соответствуют их типу. Внутренняя реализация не очень актуальна.Но, если мы хотим знать, как данные на самом деле хранятся в памяти, мы должны изучить исходный код, чтобы увидеть, что на самом деле делает программа.
В Bash 4.4 скаляры хранятся в виде строк независимо от целочисленного тега. Это видно в определении
struct variable
/SHELL_VAR
typedef и в функцииmake_variable_value
, которая явно переводит целые числа в строки для хранения.Массивы хранятся в том, что выглядит как связанный список (
array.h
), а ассоциативные массивы - в виде хеш-таблиц. Значения внутри них снова сохраняются в виде строк. Выбор связанного списка для массивов может показаться странным, но поскольку массивы могут быть разреженными, а индексы могут быть произвольными числами независимо от того, как мало элементов содержит массив, этот выбор дизайна немного легче понять.Тем не менее, код также содержит определение для неиспользуемых
union _value
, с полями для целых чисел, чисел с плавающей запятой, а также строковых значений. Он отмечен в комментарии как «на будущее», поэтому возможно, что какая-то будущая версия Bash будет хранить различные типы скаляров в их собственных формах.источник
Что касается жизни, я нигде не могу найти это в столь многих словах, но я так понимаю.
Bash является интерпретатором, а не компилятором и представляет все переменные в виде строк. Отсюда все усилия и упор, которые идут с расширениями разных видов.
Bash передает все именованные переменные в
declare
виде строк с атрибутами, которые управляют тем, как эта переменная должна быть расширена приdeclare
хранении.И конечно
Суть в том, что даже если
declare
внутреннее представление изменяется с флагами атрибутов, строки - это все, что видит или хочет видеть bash.источник
Эта страница содержит подробное руководство по вводу переменных в Bash. Этот раздел содержит больше информации о
declare
встроенной команде. Этот фрагмент кода по этой ссылке может представлять интерес:Вот
man
страница дляdeclare
.источник
Это не имеет значения.
Единственный способ взаимодействия с переменным Bash через Bash, так что это невозможно для вас , чтобы заметить разницу относительно того , как переменные хранятся в памяти, потому что вы не можете и не получить доступ к ним через память напрямую , вы всегда должны спросить Bash для их значение, и Bash может затем перевести их в какой бы путь он хочет выглядеть , как если бы они были сохранены в любом определенным образом.
На самом деле, они не могут даже быть сохранены в памяти у всех . Я не знаю, насколько умны общие реализации Bash, но, по крайней мере, в простых случаях возможно определить, будет ли использоваться переменная и / или будет ли она изменена, и полностью ее оптимизировать или встроить.
источник