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

В двух словах, в статье выше, прелагалось добавлять переменные окружения в init-скрипты шеллов, вроде .bashrc и других.

Несмотря на то, что способы, описанные там рабочие, они несут за собой неочевидные трудности.

Неочевидные трудности

  1. Если вы используете несколько шеллов одновременно (bash, zsh, fish) вам будет необходимо добавлять переменные окружение для каждого init-скрипта отдельно. И редактировать. И у всех разный синтаксис.

  2. ~/.bashrc и ему подобные предназначены только для не-login шеллов. Для login шеллов существует ~/.profile так что если хотите, чтобы переменные окружения "были видны" всем процессам в пользовательской сессии, то их нужно будет указать и там. Вот только в ~/.profile обычно есть блок:

    # if running bash
    if [ -n "$BASH_VERSION" ]; then
        # include .bashrc if it exists
        if [ -f "$HOME/.bashrc" ]; then
    	. "$HOME/.bashrc"
        fi
    fi

    что в случае с PATH продублирует все директории в ней.

  3. Если у вас "навороченный шелл", с крутым промптом (starship, oh-my-posh), удобными alias-ами, дополнительными completion-ами или другими полезностями, имеет смысл добавить следующий код в ~/.bashrc (или его аналог для других шеллов):

    # If not running interactively, don't do anything
    case $- in
        *i*) ;;
          *) return;;
    esac

    что не даст коду ниже в файле (с "наворотами") загрузится и тормозить вызовы sub-shell-ов. В этом случает "играться" с переменными окружения нужно будет до этого кода. Еще одна вещь, чтобы держать в голове.

  4. Графическим приложениям также нужны переменные окружения. ~/.profile может не считываться в современных системах с Wayland.

Выход : ~/.config/environment.d/

Переменные окружения можно объявлять в файлах в директории ~/.config/environment.d/
Файлы в ~/.config/environment.d/ считываются systemd при логине пользователя в систему. Переменные окружения объявленные там будут доступны всем процессам в системе (шеллы, CLI, TUI, GUI). Они считываются в алфавитном порядком. Несколько примеров:

/home/user/.config/environment.d/20-userdirs.conf:

# Переносим Templates директорию в share, чтобы не мешалась в /home/user/:
XDG_TEMPLATES_DIR="$HOME/.local/share/templates"

/home/user/.config/environment.d/30-user.conf :

# Настраиваем editor и pager по-умолчанию.
EDITOR="nvim"
PAGER="less -R"

# Доавляем в PATH свои дирректории
PATH="$PATH:$HOME/.local/bash"
PATH="$PATH:$HOME/.local/awk"
PATH="$PATH:$HOME/.local/bin"

/home/user/.config/environment.d/80-applications.conf:

# Настраиваем всё что душе угодно:

# Homebrew
# (output of `$ /home/linuxbrew/.linuxbrew/bin/brew shellenv`)
HOMEBREW_PREFIX="/home/linuxbrew/.linuxbrew"
HOMEBREW_CELLAR="/home/linuxbrew/.linuxbrew/Cellar"
HOMEBREW_REPOSITORY="/home/linuxbrew/.linuxbrew/Homebrew"
PATH=$PATH:"/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin"
MANPATH=$MANPATH:"/home/linuxbrew/.linuxbrew/share/man"
INFOPATH=$INFOPATH:"/home/linuxbrew/.linuxbrew/share/info"

# Rust
CARGO_HOME="$HOME/.local/cargo"
RUSTUP_HOME="$HOME/.local/rustup"
PATH=$PATH:"$CARGO_HOME/bin"

# Go
GOPATH="$HOME/.local/go"
PATH="$PATH:$GOPATH/bin"

# Change QT theme to dark
QT_STYLE_OVERRIDE=adwaita-dark

# Starship
STARSHIP_CONFIG="$HOME/.config/starship/starship.toml"

Минусы

Куда же без них:

  1. В системах без systemd это не сработает. Хотя, если у вас Linux-дистрибудив без systemd, вам, наверняка не привыкать к трудностям.

  2. Логины сессий Secure Shell-ов (SSH) и виртуальных консолей (TTY) могут не унаследовать переменные окружения, объявленные в environment.d/ файлах.

  3. Так как файлы в environment.d/ парсятся статически, их невозможно изменить в текущей сессии. Для того чтобы изменения вступили в силу, необходимо перезапустить сессию или компьютер.