Команда export — это встроенная команда оболочки Bash, которую очень удобно знать при работе в системах Linux или создании скриптов Bash.
Что делает команда export в Linux?
Команда экспорта используется для того, чтобы сделать переменные или функции в текущей оболочке доступными для дочерних процессов текущей оболочки (например, подоболочки). По умолчанию для дочернего процесса текущей оболочки доступны только переменные среды, заданные для экспорта.
В этом руководстве я покажу вам, как использовать команду export в оболочке Bash, на практических примерах, чтобы у вас не осталось никаких сомнений по этому поводу.
Давайте начнем.
Экспорт команд и среды оболочки
Чтобы понять, что делает команда export, я сначала хочу объяснить концепцию переменных среды в Linux.
Переменные среды — это переменные, которые необходимы вашей системе Linux для предоставления параметров конфигурации, требуемых оболочкой для выполнения команд.
В таблице ниже вы можете увидеть некоторые примеры переменных среды:
Переменная окружения | Описание |
HOME | Расположение домашнего каталога пользователя |
SHELL | Оболочка, используемая вашей системой |
PWD | Ваш текущий каталог |
HISTSIZE | Количество команд, доступных в истории Linux |
Вы можете использовать команду env для вывода всех переменных среды вашей оболочки.
Приведенная ниже команда egrep выводит значения четырех переменных среды, которые вы видели в таблице:
[ec2-user@ip-172-1-2-3 /]$ env | egrep "HOME|SHELL|PWD|HISTSIZE"
SHELL=/bin/bash
HISTSIZE=1000
PWD=/
HOME=/home/ec2-user
Теперь вернемся к тому, что мы говорили ранее об использовании команды export для предоставления переменных дочерним процессам нашей оболочки.
Родительские и дочерние процессы
Дочерний процесс создается родительским процессом с помощью системного вызова fork().
Вот пример. Давайте начнем с вывода PID (идентификатора процесса) текущей оболочки с помощью команды echo $$:
[ec2-user@ip-172-1-2-3 /]$ echo $$
948
Теперь я запускаю еще одну оболочку Bash внутри текущей оболочки (дочерний процесс) и использую ту же команду echo для вывода PID дочерней оболочки (подоболочки):
[ec2-user@ip-172-1-2-3 /]$ bash
[ec2-user@ip-172-1-2-3 /]$ echo $$
1050
Мы можем использовать команду ps
с флагом --ppid
, чтобы показать, что процесс с PID 1050 является дочерним процессом процесса с PID 948.
Флаг –-ppid
выбирает процессы родительского процесса с определенным PID:
[ec2-user@ip-172-1-2-3 /]$ ps --ppid 948
PID TTY TIME CMD
1050 pts/0 00:00:00 bash
Каждый процесс может быть родительским и дочерним, единственным исключением является процесс init (процесс с PID 1), который является первым процессом, запускаемым ядром как часть процесса загрузки.
Процесс init может быть только родительским по отношению к другим процессам.
Теперь, когда вы знаете, как работают родительские и дочерние процессы, давайте рассмотрим роль команды экспорта при создании дочерних процессов.
Передача переменной из родительского процесса в дочерний с помощью экспорта
Команда экспорта устанавливает атрибут экспорта переменной или функции.
Давайте посмотрим, что это означает, используя команду экспорта без флагов (или с флагом -p
).
Здесь показаны все переменные, заданные для экспорта в текущей оболочке (я использую команду head, чтобы ограничить размер вывода):
[ec2-user@ip-172-1-2-3 ~]$ export -p | head -3
declare -x HISTCONTROL="ignoredups"
declare -x HISTSIZE="1000"
declare -x HOME="/home/ec2-user"
Теперь давайте определим новую переменную с именем TESTVAR:
[ec2-user@ip-172-1-2-3 ~]$ TESTVAR=Hello
[ec2-user@ip-172-1-2-3 ~]$ echo $TESTVAR
Hello
Как видите, мы можем использовать команду echo для вывода значения нашей пользовательской переменной.
Мне интересно, что произойдет с этой переменной, если я создам дочернюю оболочку текущей оболочки (просто используя команду bash):
[ec2-user@ip-172-1-2-3 ~]$ bash
[ec2-user@ip-172-1-2-3 ~]$ echo $TESTVAR
Последняя строка вывода пуста. Это означает, что переменная TESTVAR не имеет значения в новой дочерней оболочке.
Я вернусь в родительскую оболочку (используя команду exit) и с помощью команды «export -p» посмотрю, настроен ли TESTVAR на экспорт:
[ec2-user@ip-172-1-2-3 ~]$ export -p | grep TESTVAR
[ec2-user@ip-172-1-2-3 ~]$
Это не так, и это объясняет, почему значение переменной TESTVAR в дочерней оболочке было пустым.
Именно для этого вы можете использовать команду экспорта…
…давайте сделаем следующее:
- экспортируем переменную TESTVAR, когда находимся в родительской оболочке
- используйте команду
export -p
, чтобы подтвердить, что переменная настроена для экспорта - создайте дочернюю оболочку с помощью команды bash
- подтвердите, что переменная TESTVAR имеет значение в дочерней оболочке
[ec2-user@ip-172-1-2-3 ~]$ export TESTVAR
[ec2-user@ip-172-1-2-3 ~]$ export -p | grep TESTVAR
declare -x TESTVAR="Hello"
[ec2-user@ip-172-1-2-3 ~]$ bash
[ec2-user@ip-172-1-2-3 ~]$ echo $TESTVAR
Hello
Все выглядит хорошо!
Переменная TESTVAR теперь видна в дочерней оболочке.
Передача функции из родительского процесса в дочерний с использованием экспорта
Точно так же, как мы сделали это с переменной, мы можем передать функцию дочерней оболочке.
Давайте определим однострочную функцию Bash под названием TESTFUNCTION, которая выводит сообщение в оболочке:
[ec2-user@ip-172-1-2-3 ~]$ TESTFUNCTION() { echo "This is a function"; }
[ec2-user@ip-172-1-2-3 ~]$ TESTFUNCTION
This is a function
Теперь экспортируйте функцию и убедитесь, что она доступна в подоболочке:
[ec2-user@ip-172-1-2-3 ~]$ export TESTFUNCTION
[ec2-user@ip-172-1-2-3 ~]$ export -p | grep TESTFUNCTION
declare -x TESTFUNCTION
[ec2-user@ip-172-1-2-3 ~]$ bash
[ec2-user@ip-172-1-2-3 ~]$ TESTFUNCTION
bash: TESTFUNCTION: command not found
Что-то не сработало…
…функция TESTFUNCTION не выходит из дочерней оболочки.
Почему?
Это связано с тем, что для экспорта функции с помощью команды Bash export нам необходимо передать дополнительный флаг -f
.
Давайте попробуем еще раз:
[ec2-user@ip-172-1-2-3 ~]$ export -f TESTFUNCTION
[ec2-user@ip-172-1-2-3 ~]$ export -p | grep TESTFUNCTION
declare -x TESTFUNCTION
[ec2-user@ip-172-1-2-3 ~]$ bash
[ec2-user@ip-172-1-2-3 ~]$ TESTFUNCTION
This is a function
Здорово, на этот раз сработало.
Команда Bash Export для переменных в одной строке
До сих пор в наших примерах мы использовали отдельные команды для определения переменной или функции, а затем экспортировали ее с помощью команды export.
Если мы хотим экспортировать переменную, то эти две вещи можно сделать с помощью одной команды экспорта в одной строке.
Давайте посмотрим, как это выглядит:
export TESTVAR=Hello
Имеет ли это смысл?
Помощь экспортной команде
Обычно для изучения того, как использовать команду, очень удобно использовать команду man.
Давайте сделаем это с помощью команды экспорта:
man export
По какой-то причине мы просто не получаем руководство по команде экспорта.
Мы также получаем вручную для других команд (например, cd, echo, ulimit, umasks и многих других).
Это связано с тем, что команда export является встроенной командой оболочки Bash вместе с другими командами.
Для встроенных команд оболочки проще использовать команду help:
help export
Это показывает следующий вывод:
Мы уже рассмотрели флаги -f
и -p
.
Давайте посмотрим, как работает флаг -n
. Согласно справке, этот флаг можно использовать для удаления экспортируемого свойства из переменной.
[ec2-user@ip-172-1-2-3 ~]$ echo $TESTVAR
Hello
[ec2-user@ip-172-1-2-3 ~]$ export TESTVAR
[ec2-user@ip-172-1-2-3 ~]$ export -p | grep TESTVAR
declare -x TESTVAR="Hello"
[ec2-user@ip-172-1-2-3 ~]$ export -n TESTVAR
[ec2-user@ip-172-1-2-3 ~]$ export -p | grep TESTVAR
Это подтверждает, что после использования команды export -p
переменная TESTVAR больше не отображается в списке переменных, отмеченных для экспорта.
Команда Export и переменная среды Path
Переменная окружения PATH — одна из важнейших переменных в системе Linux. Она предоставляет оболочке список каталогов, в которых следует искать исполняемые файлы при выполнении команды пользователем. Она позволяет выполнять команды, не зная полного пути к их исполняемым файлам.
Когда я открываю оболочку Linux, переменная среды PATH уже определена:
[ec2-user@ip-172-1-2-3 ~]$ env | grep PATH
PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/ec2-user/.local/bin:/home/ec2-user/bin
Почему?
Это потому, что он автоматически определяется и экспортируется в файл .bash_profile, расположенный в домашнем каталоге моего пользователя.
Этот файл используется по умолчанию для инициализации пользовательской среды.
[ec2-user@ip-172-1-2-3 ~]$ pwd
/home/ec2-user
[ec2-user@ip-172-1-2-3 ~]$ grep PATH.bash_profile
PATH=$PATH:$HOME/.local/bin:$HOME/bin
export PATH
Вы можете обновить файл.bash_profile, если хотите добавить больше каталогов в переменную PATH.
Обратите внимание, что каталоги в переменной PATH должны быть разделены двоеточием (:).
Заключение
Команда export — одна из команд Linux, относительно которой у людей часто возникают сомнения.
Часто можно увидеть, как люди используют команду экспорта, не имея полного представления о том, что за ней стоит и как она связана с дочерними процессами.
Надеюсь, это руководство оказалось для вас полезным и ответило на все ваши вопросы о команде Bash export.