Зачем мне использовать объявление / typeset в сценарии оболочки вместо просто X = y? - PullRequest
1 голос
/ 06 июня 2019

Я недавно натолкнулся на сценарий оболочки, который использует declare -- FOO="", который, по-видимому, пишется typeset -- FOO="" в оболочках не-bash.

Почему я могу захотеть сделать это вместо простого FOO="" илиexport FOO

Ответы [ 2 ]

3 голосов
/ 06 июня 2019

Наиболее важной целью использования declare является управление областью действия или использование типов массивов, которые иначе недоступны.


Использование функционально-локальных переменных

Чтобы дать вам пример:

print_dashes() { for (( i=0; i<10; i++; do printf '-'; done; echo; }

while read -p "Enter a number: " i; do
  print_dashes
  echo "You entered: $i"
done

Вы ожидаете, что это напечатает номер, введенный пользователем, верно? Но вместо этого он всегда будет печатать значение i, которое print_dashes оставляет после завершения.

Рассмотрим вместо этого:

print_dashes() {
  declare i  # ''local i'' would also have the desired effect
  for (( i=0; i<10; i++; do printf '-'; done; echo;
}

... сейчас i является локальным , поэтому вновь назначенное значение не сохраняется после его вызова.


Объявление явно глобальных переменных

Наоборот, иногда вы хотите объявить глобальную переменную и дать понять читателям вашего кода, что вы делаете это с помощью намерения , или сделать это при объявлении чего-либо как массива (или в противном случае declare в противном случае неявно указывает глобальное состояние). Вы можете сделать это тоже:

myfunc() {
  declare arg                     # make arg local
  declare -g -A myfunc_args_seen  # make myfunc_args_seen a global associative array
  for arg; do
    myfunc_args_seen["$arg"]=1
  done

  echo "Across all invocations of myfunc, we have seen the following arguments:"
  printf ' - %q\n' "${!myfunc_args_seen[@]}"
}

Объявление ассоциативных массивов

Обычный Массивы оболочки можно просто назначить: my_arr=( one two three )

Однако это не относится к ассоциативным массивам, которые обозначаются как строки. Для них вам нужно объявить их:

declare -A my_arr=( ["one"]=1 ["two"]=2 ["three"]=3 )
1 голос
/ 06 июня 2019
declare -i cnt=0

объявляет переменную только для целых чисел, которая быстрее для математики и всегда вычисляется в арифметическом контексте.

declare -l lower="$1"

объявляет переменную, которая автоматически переводит в нижний регистр все, что помещено в нее, без какого-либо специального синтаксиса наaccess.

declare -r unchangeable="$constant"

объявляет переменную только для чтения.

Посмотрите на https://unix.stackexchange.com/questions/254367/in-bash-scripting-whats-the-different-between-declare-and-a-normal-variable для некоторого полезного обсуждения - вам могут не понадобиться эти вещи часто, но если выне знаю, что доступно, вы, вероятно, будете работать усерднее, чем должны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...