-a- для создания индексированных массивов NAME (если поддерживается)

-a- для создания индексированных массивов NAME (если поддерживается)

Я стремлюсь понять общую концепцию «переменных атрибутов», надеясь, что это поможет мне понятьчто такое декларация в Bash.

Что такое атрибут переменной? Зачем кому-то может понадобиться присвоить атрибут переменной? Почему простого создания переменных и их расширения при выполнении недостаточно при работе с переменными?

решение1

Обычно переменная — это место для хранения значения. Вы присваиваете значение переменной ( var="some value"), и после этого вы можете вызвать значение с помощью расширения переменной (запись "$var"эквивалентна записи "some value").

Можно создать переменные, которые делают что-то особенное, когда вы присваиваете им значение или в других обстоятельствах, когда оболочка обращается к переменным. Атрибут переменной — это аннотация, которую оболочка сохраняет рядом с именем и значением переменной, что сообщает оболочке о необходимости применять это особое поведение.

Один пример

declare -i xсообщает оболочке, что xдолжно содержать только целочисленные значения. Обычно, когда вы присваиваете значение переменной, оболочка берет строку, которая получается в результате расширения правой части знака равенства, и сохраняет ее как значение переменной. Но если переменная имеет атрибут integer, оболочка анализирует эту строку как арифметическое выражение и сохраняет результат вычисления этого выражения. Например:

$ x=2+2; echo $x
2+2
$ declare -i x; x=2+2; echo $x
4
$ declare -i x; x=2+hello; echo $x
2
$ declare -i x; x=2+
bash: 2+: syntax error: operand expected (error token is "+")

(Третья строка с x=2+helloустановками xв 2, поскольку helloэто имя переменной, которое не определено, а неустановленные переменные по умолчанию молча интерпретируются как 0.)

Еще примеры

  • declare -l varобъявляет, что varдолжно содержать только строчные буквы. Когда оболочка сохраняет значение переменной, она преобразует любую заглавную букву в строчную.
  • declare -u varвыполняет преобразование в обратном направлении.
  • declare -r varделает его varдоступным только для чтения, что также является особым поведением присваивания: оно приводит к тому, что каждое последующее присваивание завершается varнеудачей.
  • declare -x varвызывает varэкспорт в среду. Для этого атрибута особое поведение происходит, когда bash запускает внешнюю команду: внешние команды видят среду, содержащую переменные, которые оболочка экспортирует в то время, когда оболочка запускает внешнюю команду.

решение2

От help declare:

Options which set attributes:
    -a  to make NAMEs indexed arrays (if supported)
    -A  to make NAMEs associative arrays (if supported)
    -i  to make NAMEs have the `integer' attribute
    -l  to convert the value of each NAME to lower case on assignment
    -n  make NAME a reference to the variable named by its value
    -r  to make NAMEs readonly
    -t  to make NAMEs have the `trace' attribute
    -u  to convert the value of each NAME to upper case on assignment
    -x  to make NAMEs export

Примечание: declareтакже может использоваться для функций.

Каждый из этих атрибутов имеет одно или несколько применений:


-a- для создания индексированных массивов NAME (если поддерживается)

Это не совсем необходимо, поскольку установка параметра как массива автоматически объявит его как индексированный массив. Использование этого может сделать ваш код более очевидным и читаемым.


-A- для создания ассоциативных массивов NAME (если поддерживается)

Насколько мне известно, это совершенно необходимо, поскольку попытка задать ассоциативный массив без предварительного его объявления приведет к созданию индексированного массива.

$ assoc=([foo]=bar)
$ declare -p assoc
declare -a assoc=([0]="bar")
$ unset assoc
$ declare -A assoc
$ assoc=([foo]=bar)
$ declare -p assoc
declare -A assoc=([foo]="bar" )

-i- чтобы ИМЕНА имели атрибут `integer'

Полезно, если вы хотите убедиться, что ваш параметр можеттолькохранить целые числа. Это также позволяет выполнять арифметическое расширение при присваивании.

$ declare -i a
$ a=foo
$ echo $a
0
$ a=1+1
$ echo $a
2

-l- для преобразования значения каждого ИМЕНИ в нижний регистр при назначении

Гарантирует, что значение ваших параметров всегда будет в нижнем регистре. Это довольно крутая функция, о которой я не знал и, вероятно, буду использовать в будущем. Она устраняет необходимость в сложном расширении параметров или использовании отдельной утилиты, такой какtr

$ declare -l foo=Bar
$ echo $foo
bar

-n- сделать NAME ссылкой на переменную, названную по ее значению

Как косвенная ссылка. Это может исключить использование evalво многих сценариях.

$ a=foo
$ declare -n b=a
$ echo $b
foo

-r- сделать ИМЕНА доступными только для чтения

Это хорошая функция. Она может быть особенно полезна для переменных оболочки/окружения, которые вы хотите установить один раз и убедиться, что они не будут изменены.

$ declare -r foo=bar
$ echo $foo
bar
$ foo=baz
-bash: foo: readonly variable

-t- чтобы ИМЕНА имели атрибут `trace'

Я не уверен насчет этого. Я думаю, это может применяться только к функциям.


-u- для преобразования значения каждого ИМЕНИ в верхний регистр при назначении

Похож на -l, но противоположен

$ declare -u foo=bAr
$ echo $foo
BAR

-x- сделать так, чтобы ИМЕНА экспортировались

Еще один способ экспортировать переменные в среду.


Связанный контент