По умолчанию ссылка на неопределенные (или «неустановленные») имена переменных в сценариях оболочки просто дает пустую строку. Но есть исключение: если оболочка запускается с опцией -u
или set -u
, в ней выполняются расширения неустановленных переменных, которые рассматриваются как ошибки и (если оболочка не является интерактивной) приводит к ее завершению. Bash также применяет этот принцип к элементам массива:
$ array=(zero one two)
$ echo "${array[3]}"
$ echo "array[3] = '${array[3]}'"
array[3] = ''
$ set -u
$ echo "array[3] = '${array[3]}'"
-bash: array[3]: unbound variable
Существуют также модификаторы, которые можно использовать для управления действиями расширений, если переменная (или элемент массива) не определена и / или пуста (определяется как пустая строка):
$ array=(zero one '')
$ echo "array[2] is ${array[2]-unset}, array[3] is ${array[3]-unset}"
array[2] is , array[3] is unset
$ echo "array[2] is ${array[2]:-unset or empty}, array[3] is ${array[3]:-unset or empty}"
array[2] is unset or empty, array[3] is unset or empty
Существует множество других вариантов, см. стандарт синтаксиса оболочки POSIX , раздел 2.6.2 (расширение параметров).
Кстати, вам нужно использовать фигурные скобки (как я делал выше) вокруг всего, кроме простой ссылки на переменную. $name[2]
- это ссылка на обычную переменную name
(или элемент 0, если это массив), за которой следует строка "[2]"; ${name[2]}
, с другой стороны, является ссылкой на элемент 2 массива name
. Кроме того, вы почти всегда хотите заключать ссылки на переменные в двойные кавычки (или включать их в строки в двойных кавычках), чтобы предотвратить «полезное» разбиение оболочки на слова и / или развертывание их в списки соответствующих файлов. Например, этот тест:
if [ $my_array[i] = true ]
(в основном) эквивалентно:
if [ ${my_array[0]}[i] = true ]
... это совсем не то, что вы хотите. Но вот этот:
if [ ${my_array[i]} = true ]
по-прежнему не работает, потому что если my_array[i]
не установлено (или пусто), оно расширится до эквивалента:
if [ = true ]
... неверный синтаксис тестового выражения. Вы хотите это:
if [ "${my_array[i]}" = true ]