Область переменных окружения

Вопрос или проблема

Ранее я думал, что переменные окружения определяются в области процесса, и если они экспортируются, то передаются дочерним процессам.

Таким образом, я хотел найти единственное место для определения моих переменных окружения и чтобы они были доступны для:

  1. Сервиса пользователя, определенного в ~/.config/systemd/user/start-up.service
  2. Файла hyprland.conf
  3. Оболочки ZSH

Я использую Arch Linux с SDDM, Hyprland, терминалом Kitty и оболочкой ZSH. Я попробовал несколько решений, и единственным работающим был вариант определения переменных окружения в файле hyprland.conf (на самом деле, во внешнем файле, подключаемом Hyprland), и иметь дублирующее определение для двух переменных окружения, необходимых сервису, в поле Environment сервиса. Я не могу использовать EnvironmentFile, так как между форматами, ожидаемыми Hyprland и файлами сервисов, существует несоответствие. Мне не нравится это решение из-за дублирования.

Но в процессе моего исследования я обнаружил очень неожиданную вещь: все переменные окружения, определенные в hyprland.conf, видны в оболочке ZSH, хотя оболочка не является дочерним процессом Hyprland.

pstree
systemd─┬─NetworkManager───4*[{NetworkManager}]
        ├─dbus-daemon
   ==>  ├─kitty─┬─zsh───pstree
        │       └─2*[{kitty}]
        ├─polkitd───3*[{polkitd}]
        ├─rtkit-daemon───2*[{rtkit-daemon}]
        ├─sddm─┬─Xorg───2*[{Xorg}]
   ==>  │      ├─sddm-helper───Hyprland───4*[{Hyprland}]
        │      └─{sddm}
        ├─sh───sleep
        ├─ssh-agent
        ├─systemd─┬─(sd-pam)
        │         ├─dbus-daemon
        │         ├─gnome-keyring-d───4*[{gnome-keyring-d}]
        │         ├─pipewire───2*[{pipewire}]
        │         ├─pipewire-pulse───2*[{pipewire-pulse}]
        │         ├─wireplumber───6*[{wireplumber}]
        │         ├─2*[xdg-desktop-por───4*[{xdg-desktop-por}]]
        │         ├─xdg-document-po─┬─fusermount3
        │         │                 └─6*[{xdg-document-po}]
        │         └─xdg-permission-───3*[{xdg-permission-}]
        ├─systemd-journal
        ├─systemd-logind
        ├─systemd-timesyn───{systemd-timesyn}
        ├─systemd-udevd
        ├─upowerd───3*[{upowerd}]
        └─wpa_supplicant

Таким образом, у меня на самом деле два вопроса:

  1. Существует ли единственное место для определения переменных окружения (которые должны определяться на уровне пользователя, а не системы), чтобы они были видны для сервиса пользователя, Hyprland и оболочки?
  2. Как возможно, что переменные, определенные в hyprland.conf, видны его дочернему процессу?

Я наткнулся на этот вопрос, пытаясь разобраться с настройкой PATH в swaywm, поэтому думаю, что наши мотивы схожи. Я не являюсь экспертом в POSIX или C, но вот что я думаю после прочтения соответствующих страниц руководства и исходного кода GLIBC (поправки приветствуются):

  1. “Окружение” – это строка специфичная для каждого процесса. Вы можете узнать, с чем процесс был создан из /proc/(pid)/environ, но это не означает, что строка не была изменена с тех пор.

  2. Когда программа использует GLIBC, новые процессы инициируются с помощью семейства функций C exec. Некоторые из них неявно копируют переменную environ для новых процессов, некоторые позволяют передать новую в качестве аргумента (например, execle и т.д.). С этого момента два процесса не разделяют окружение. Таким образом, дочерний процесс может получить окружение родительского процесса, но после этого, если родитель изменяет свое собственное (например, с помощью setenv), окружение дочернего процесса останется неизменным.

  3. В Unix/Linux нет “глобального окружения”. Это просто процессы, передающие спецификации окружения своим детям. Существуют механизмы для чтения переменных окружения в определенный момент (например, см. вики Arch), но это всего лишь соглашения.

  4. Оболочки ведут список переменных, который отличается от их environ. В большинстве оболочек export FOO просто означает “добавить FOO к environ при запуске новых процессов.”

Я предполагаю, что переменные окружения, попадающие в вашу zsh, не исходят из непарентного процесса, а могут быть результатом предыдущей попытки конфигурации, о которой вы могли забыть.

Ответ или решение

Область применения переменных окружения в Linux

Переменные окружения играют ключевую роль в конфигурации процессов и управлении настройками в операционных системах на базе Unix/Linux. Понимание их области применения и способа работы может значительно упростить администрирование системы. В этой статье мы рассмотрим два основных вопроса, связанные с переменными окружения, заданные в контексте использования Arch Linux с графическим окружением Hyprland и оболочкой Zsh.

1. Единственное место определения переменных окружения

Для достижения цели создания единой точки определения переменных окружения, которая будет доступна как для пользовательских сервисов systemd, так и для всех процессов, запущенных в частности графическим окружением и оболочкой, существует несколько вариантов:

  • Использование файлов конфигурации:
    Переменные окружения можно определять в различных файлах конфигурации, таких как ~/.bashrc, ~/.zshrc или даже в .profile. Эти файлы выполняются при запуске соответствующей оболочки и могут содержать команды export VAR_NAME=value, что сделает переменные доступными для всех дочерних процессов.

  • Конфигурация в системных файлах:
    В некоторых случаях имеет смысл использовать файл ~/.config/environment, который автоматически считывается графическими окружениями, или определять переменные в конфигурационных файлах самих системных демонов, таких как злободневные .desktop файлы в директории ~/.config/autostart/.

  • Системные средства управления окружением:
    Некоторые пользователи предпочитают использовать такие инструменты, как env, setenv, или специализированные скрипты для задания окружения, которые затем вызываются на старте сессии.

Заметьте, что переменные, указанные в сервисных единицах systemd, могут быть указаны непосредственно в файле службы (например, в Environment=), однако, учитывая вашу ситуацию с Hyprland, надо быть осторожным из-за несоответствий форматов.

2. Видимость переменных окружения в оболочке Zsh

Вы удивлены тем, что переменные, определенные в файле конфигурации Hyprland, видны в Zsh, несмотря на то, что Zsh не является дочерним процессом Hyprland. Это может происходить по нескольким причинам:

  • Наследование переменных окружения:
    Elementy окружения могут быть определены в одноименных файлах конфигурации, которые загружаются на уровне сессии. Например, если файл конфигурации Hyprland инициализирует окружение во время старта сессии, это может оказать влияние на общие параметры окружения.

  • Передача во время инициализации:
    Когда Hyprland запускается, он может инициировать сессию, при этом экспортируя переменные окружения в контекст системы. Sixube, в этом случае Zsh может получить доступ к этим переменным, поскольку они были установлены на этапе инициализации рабочего окружения.

  • Конфигурация единого окружения:
    Ваша система может использовать унифицированный менеджер сессий, который обрабатывает и передает переменные окружения через общие методы, такие как D-Bus или другие слои абстракции. Это позволяет такие параметры как PATH, EDITOR, и другие переменные быть доступными для всех клиентов.

Заключение

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

Для всестороннего управления окружением создайте обобщенный файл конфигурации или используйте системные утилиты, чтобы гарантировать, что все нужные переменные будут доступны для ваших сервисов и оболочек без дублирования.

Оцените материал
Добавить комментарий

Капча загружается...