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

Содержание
Переменные окружения и 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.
Добавить путь в PATH навсегда: .bashrc или .profile
Bash читает разные файлы в зависимости от того, как запущен. Отсюда вечный вопрос, куда писать.
| Файл | Когда читается | Что туда писать |
|---|---|---|
~/.bashrc | каждый интерактивный bash: новое окно терминала, вкладка | алиасы, приглашение, PATH для терминала |
~/.profile | вход в систему (login shell), в Ubuntu и Debian также графический вход | переменные для всей сессии |
~/.bash_profile | login shell bash; если файл есть, ~/.profile не читается | обычно подключает ~/.bashrc |
~/.config/environment.d/*.conf | сессия systemd --user, графические приложения | переменные для GUI |
/etc/environment | любой вход через PAM | общие переменные без подстановок |
/etc/profile.d/*.sh | login 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, перечислив нужные каталоги.
Документация и источники
- environment.d - Definition of user service environment, freedesktop.org, systemd, 2026
- Bash Reference Manual: Bash Startup Files, GNU Project, 2025
- fish_add_path, fish shell documentation, 2026
Читайте также
Команды проверены на актуальных версиях дистрибутивов на момент обновления. Перед изменением системных настроек сделайте резервную копию.