Вот и до наших краёв донеслась снежная стихия, какая-то «Ольга». Ну хоть не «Арбузова». С названием переменных явно не заморачивались. Ну да ладно, сегодня тоже будет про переменные в Bash.

Не все понимают чем отличается определение переменной в Bash c export и без. Сейчас расскажу, чтобы ты больше не сомневался.

Есть 2 распространенных способа объявить переменную:

export var=значение
var=значение

Что тут не так? А тут всё так. Только в первом случае я использую export, чтобы сделать переменную доступной для подпроцессов.

То есть, переменная заданная через export будет доступна для любого процесса, который будет запущен в рамках процесса оболочки.

А если задать переменную БЕЗ export, то переменная будет доступна только в самой оболочке и недоступна для других процессов.

Скучная теория, давай на практике:

var1="Hello Bashdays"
echo $var1

Hello Bashdays

Запускаем, смотрим, ага переменная задается без экспорта и выводится на экран. Идем дальше и запускаем это:

export var1
var2="Bye, Bye"
bash
echo $var1

Hello Bashdays

echo $var2
  1. Экспортируем var1
  2. Объявляем вторую переменную var2
  3. Запускаем bash в bash (подпроцесс)
  4. Получаем значение переменной var1
  5. Получаем значение переменной var2

В пятом пункте переменная var1 вывелась на экран даже после того, как я запустил еще одну оболочку bash внутри оболочки bash. Переменная стала доступна для подпроцессов.

А вот var2 которую я объявил во втором пункте, куда-то делась. На самом деле она никуда не делась, просто подпроцесс её не видит. Стоит мне сейчас сделать так:

exit
echo $var2

Bye, Bye

Я получаю значение переменной var2.

Роман Шубин
Роман Шубин
CEO & CTO, Главред в «Цифровой улей»
Задать вопрос
Если уж совсем грубо говоря, export делает переменную глобальной на уровне подпроцессов.

Ну и частые ошибки, когда пытаешься экспортировать массив:

export Array=("Hello" "Bashdays")

С виду все в порядке и вроде логично, ошибок нет. НО в подпроцессах если попытаться вывести содержимое этого массива, ты получишь пустоту. И люди на это убивают несколько часов, чтобы понять в чем причина.

Но где наша не пропадала, если уж совсем хочется, то можно преобразовать массив в строку и затем экспортировать эту строку. Делается это так:

Array=("Hello" "BashDays")
export ArrayString="$(printf "%s|" "${Array[@]}")"
IFS='|' read -ra Array <<< "$ArrayString"
echo "${Array[@]}"

Значок собаки = все элементы массива, его можно справедливо заменить на 1, 2, 3 и т.п. А printf используется для форматирования массива в строку, разделяя элементы символом «|».

Теперь массив экспортирован и будет доступен в подпроцессах.

Вообще холиваров на тему экспортирования переменных очень много, каждый топит за своё, но тут уже хозяин барин. Как говорится под каждую задачу своё решение, где-то необходим export, где-то он и не нужен.

Ладно чо, хороших тебе предстоящих выходных и береги себя!