LinuxRuLinux без лишней теории
Терминал и bash

Переменные окружения и PATH в Linux: как добавить путь навсегда

Редакция LinuxRu6 мин чтенияИнструкции

Переменная PATH в Linux хранит список каталогов, где оболочка ищет команды: временно путь добавляют через export PATH="$HOME/bin:$PATH", а навсегда ту же строку дописывают в ~/.bashrc или ~/.profile. Для всех пользователей служит /etc/environment, для программ из меню рабочего стола - файлы в ~/.config/environment.d.

Переменные окружения и PATH в Linux: как добавить путь навсегда
Фото: BunsenLabs Community, GPL, Wikimedia Commons
Содержание
  1. Что это
  2. Как работает PATH
  3. Временно
  4. Навсегда для себя
  5. zsh и fish
  6. Для всех пользователей
  7. Графические приложения
  8. sudo, cron, systemd
  9. Сломанный PATH
  10. Частые вопросы

Переменные окружения и PATH: что это и как их посмотреть

Переменная окружения - пара "имя=значение", которую процесс получает от родителя при запуске. Через них программы узнают домашний каталог (HOME), язык (LANG), редактор по умолчанию (EDITOR) и, главное, где искать команды (PATH).

printenv            # все переменные окружения
echo "$PATH"        # список каталогов через двоеточие
echo "$HOME $SHELL $LANG"
printenv PATH | tr ':' '\n'   # PATH по строке на каталог

Типичный PATH в Ubuntu 26.04 выглядит так:

/home/user/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/snap/bin

Есть ещё переменные оболочки: x=5 создаёт переменную, которую видит только текущий bash. Дочерним процессам она достанется лишь после export. Отсюда частая путаница: переменная "есть", а запущенная программа её не видит. Если терминал для вас пока в новинку, начните с базовых команд Linux.

Как оболочка ищет команду по PATH

Когда вы вводите htop, bash проверяет алиасы и встроенные команды, а потом перебирает каталоги из PATH слева направо и запускает первый найденный исполняемый файл. Порядок решает: если ~/.local/bin стоит раньше /usr/bin, ваша версия программы перекроет системную.

type -a python3      # все найденные варианты по порядку
command -v node      # какой файл реально запустится
hash -r              # сбросить кэш путей bash после установки новой программы

Текущий каталог в PATH не входит, поэтому скрипт рядом запускают как ./script.sh. Не добавляйте . в PATH: любой файл с именем ls в чужой папке выполнится вместо системного.

Временно: export в текущей сессии

export EDITOR=nano
export PATH="$HOME/tools/bin:$PATH"   # добавить каталог в начало
export PATH="$PATH:/opt/app/bin"      # добавить в конец
unset EDITOR                          # удалить переменную
LANG=C ls --help                      # переменная только для одной команды

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

Обратите внимание на $PATH внутри значения. Строка export PATH=/opt/app/bin без него заменит весь список, и в этом терминале перестанут находиться ls и sudo.

Bash читает разные файлы в зависимости от того, как запущен. Отсюда вечный вопрос, куда писать.

ФайлКогда читаетсяЧто туда писать
~/.bashrcкаждый интерактивный bash: новое окно терминала, вкладкаалиасы, приглашение, PATH для терминала
~/.profileвход в систему (login shell), в Ubuntu и Debian также графический входпеременные для всей сессии
~/.bash_profilelogin shell bash; если файл есть, ~/.profile не читаетсяобычно подключает ~/.bashrc
~/.config/environment.d/*.confсессия systemd --user, графические приложенияпеременные для GUI
/etc/environmentлюбой вход через PAMобщие переменные без подстановок
/etc/profile.d/*.shlogin shell всех пользователейсистемные пути для shell

Для одного пользователя и работы в терминале хватает ~/.bashrc. Защититься от дублей при повторном source помогает проверка:

case ":$PATH:" in
  *":$HOME/.local/bin:"*) ;;
  *) export PATH="$HOME/.local/bin:$PATH" ;;
esac
nano ~/.bashrc     # дописать строку в конец
source ~/.bashrc   # применить без перезапуска терминала

В Ubuntu и Debian стандартный ~/.profile уже добавляет ~/bin и ~/.local/bin, если эти каталоги существуют. Поэтому pipx и скрипты в ~/.local/bin начинают работать после первого перелогина без правок. В Fedora то же делает ~/.bashrc. Если вы держите в .bashrc много своих команд, посмотрите и статью про алиасы.

zsh и fish: свои файлы и синтаксис

Если echo $SHELL показывает не bash, файлы другие.

zsh

Интерактивные настройки идут в ~/.zshrc, переменные для всех запусков zsh (в том числе скриптов) можно задать в ~/.zshenv. У zsh есть массив path, связанный с PATH:

# ~/.zshrc
typeset -U path          # убирать дубли автоматически
path=("$HOME/.local/bin" $path)
export EDITOR=nvim

fish

fish не читает .bashrc и использует свой синтаксис. Для PATH есть готовая функция, которая сохраняет путь навсегда сама:

fish_add_path ~/.local/bin
set -Ux EDITOR nvim      # универсальная экспортируемая переменная

Для всех пользователей: /etc/environment и /etc/profile.d

/etc/environment читает модуль pam_env при любом входе: графическом, в консоль, по SSH. Это не скрипт, а список строк ИМЯ=значение. Подстановка $PATH и команда export здесь не работают, PATH записывают целиком:

PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/opt/app/bin"
JAVA_HOME="/usr/lib/jvm/java-21-openjdk-amd64"

Для shell-логики удобнее отдельный файл в /etc/profile.d/, он подключается из /etc/profile при входе в login shell:

echo 'export PATH="$PATH:/opt/app/bin"' | sudo tee /etc/profile.d/app.sh

Изменения в обоих местах применяются после выхода из системы и нового входа. Файл ~/.pam_environment по умолчанию больше не читается начиная с PAM 1.5, не полагайтесь на старые инструкции с ним.

Переменные для графических приложений

Программа, запущенная из меню или ярлыком, не проходит через ~/.bashrc: её запускает графическая сессия, а не терминал. Поэтому редактор кода из меню может не видеть путь, который отлично работает в консоли.

Надёжный способ для GNOME и KDE Plasma с systemd - environment.d. Файл в ~/.config/environment.d/ с расширением .conf поддерживает подстановку переменных:

mkdir -p ~/.config/environment.d
cat > ~/.config/environment.d/10-path.conf <<'EOF'
PATH=$HOME/.local/bin:$HOME/go/bin:$PATH
EDITOR=nano
EOF
systemctl --user show-environment | grep -E '^(PATH|EDITOR)='   # проверка после перелогина

Синтаксис описан в man environment.d. В KDE Plasma есть и свой механизм: shell-скрипты из ~/.config/plasma-workspace/env/*.sh выполняются при старте сессии, там работает обычный export.

Если программа из меню не видит переменную, проверьте, что получила именно она: найдите PID через pgrep -f имя и выполните tr '\0' '\n' < /proc/PID/environ | grep PATH. Так сразу понятно, проблема в настройке сессии или в самой программе.

sudo, cron и службы systemd

sudo сбрасывает окружение и подставляет PATH из параметра secure_path в /etc/sudoers. Поэтому sudo mytool пишет "command not found", хотя без sudo всё запускается. Варианты: указать полный путь, sudo env "PATH=$PATH" mytool или положить ссылку в /usr/local/bin. Как устроены права и sudoers, описано в статье про пользователей и sudo.

cron запускает задачи с минимальным PATH, обычно /usr/bin:/bin. Пишите полные пути или задайте переменную в начале crontab:

PATH=/usr/local/bin:/usr/bin:/bin
0 3 * * * backup.sh

systemd-службы не читают профили вовсе. Переменные задают в юните директивами Environment= или EnvironmentFile=, удобнее через sudo systemctl edit имя.service (подробнее в шпаргалке по systemctl). В bash-скриптах для cron и служб тоже лучше явно объявлять PATH в начале, об этом подробнее в руководстве по bash-скриптам.

Если сломали PATH: как починить

Симптом узнаётся сразу: после правки .bashrc в новом терминале ls, nano и sudo отвечают "command not found". Значит, PATH перезаписан, а не дополнен. Верните стандартное значение в текущей сессии и исправьте файл, обращаясь к редактору по полному пути:

export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
/usr/bin/nano ~/.bashrc

Если сломан /etc/environment и в графическую сессию не войти, переключитесь в консоль Ctrl+Alt+F3, войдите и поправьте файл через /usr/bin/sudo /usr/bin/nano /etc/environment. Другие типичные ошибки: пробелы вокруг = (PATH = ... bash воспримет как команду), путь с тильдой в кавычках ("~/bin" не раскрывается, пишите $HOME/bin) и точка с запятой вместо двоеточия между каталогами.

Частые вопросы

Чем ~/.bashrc отличается от ~/.profile?

~/.bashrc выполняется в каждом новом интерактивном bash, то есть в каждом окне терминала. ~/.profile читается один раз при входе в систему и влияет на всю сессию. PATH для терминала можно задать в .bashrc, для всей сессии надёжнее .profile или environment.d.

Почему после изменения .bashrc ничего не поменялось?

Файл читается при запуске оболочки. Выполните source ~/.bashrc или откройте новый терминал. Для изменений в .profile, /etc/environment и environment.d нужно выйти из системы и войти заново.

Как посмотреть все переменные окружения?

Команда printenv или env выводит переменные текущего процесса. Значение одной переменной покажет printenv PATH или echo "$PATH".

Почему sudo не видит мою программу?

sudo заменяет PATH значением secure_path из /etc/sudoers. Запустите программу по полному пути, создайте ссылку в /usr/local/bin или используйте sudo env "PATH=$PATH" команда.

Как удалить каталог из PATH?

Уберите строку, которая его добавляет, из .bashrc, .profile или environment.d и откройте новую сессию. В текущем терминале можно переопределить PATH вручную через export, перечислив нужные каталоги.

Документация и источники

Читайте также

Команды проверены на актуальных версиях дистрибутивов на момент обновления. Перед изменением системных настроек сделайте резервную копию.