Команда 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

Это показывает следующий вывод:

Страница справки по команде экспорта Linux

Мы уже рассмотрели флаги -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.

Written by Иван Васильков

Системный администратор и DevOps с опытом 10+ лет.