LINUX.ORG.RU

Как правильно пробросить PATH в systemd --user?

 , , ,


0

1

В Ubuntu 22.04 c Wayland запускаю демон emacs через systemd:

~/.config/systemd/user/emacs.service

[Unit]
Description=Emacs text editor
Documentation=info:emacs man:emacs(1) https://gnu.org/software/emacs/

[Service]
Type=notify
ExecStart=/usr/bin/emacs --fg-daemon

# Emacs will exit with status 15 after having received SIGTERM, which
# is the default "KillSignal" value systemd uses to stop services.
SuccessExitStatus=15

# The location of the SSH auth socket varies by distribution, and some
# set it from PAM, so don't override by default.
# Environment=SSH_AUTH_SOCK=%t/keyring/ssh
Restart=on-failure

[Install]
WantedBy=default.target

В .profile задан необходимый мне PATH, и импортирование его в systemd:

export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH

systemctl --user import-environment PATH

Но после загрузки системы emacs не хочет видеть мой путь (конкретнее, run-python не находит python), хотя если я перезапускаю emacs.service из командной строки, все работает.

Соответственно, вопрос: как правильно задать PATH, чтобы при загрузке системы он считывался до того, как запустится emacs.service?


Не очень понятно для чего вообще запускать emacs на системном уровне? Добавь в автозапуск сессии и всё.

no-such-file ★★★★★
()

да что вы за говном вечно занимаетесь возьми нужный тебе дистрибутив без этого системдэ настрой под свою задачу и запускай отдельно на железке или виртуалке

Spoofing ★★★★★
()

@no-such-file, на предыдущей бубунте я так и делал - клал запуск демона в автозагрузку, - но проблема была та же, поэтому стал запускать через systemd (к тому же, systemd предназначен для запуска сервисов, так почему бы не использовать его для запуска сервисов?), и это работало (по крайней мере, я не помню, чтобы приходилось перезапускать сервис вручную), пока недавно не обновил бубунту.

@e1nste1n, спасибо, почитаю, пока я понял, что там копируется переменная из окружения шелла в окружение емакса, но если я запускаю сервис вручную из шелла, а не сам он запускается во время старта системы, то все работает, т.е. по идее необходимости в каком-то копировании нет, а требуется правильно выстроить последовательность запуска. В общем,

не могли бы объяснить, в чём, собственно, проблема? В моём представлении, ситуация такая:

  1. systemd запускает пользовательские сервисы в чистом окружении, а не читает стандартные конфигурационные файлы, вроде .profile.

  2. при логине в систему запускается логин-шелл, считывающий .profile; все остальное запускается из этого «корневого» логин-шелла

  3. в .profile задан PATH и инструкция импорта этой переменной в systemd.

  4. предполагаемая последовательность при загрузке: логин-шелл -> .profile -> systemd -> сервис

  5. почему тогда не работает?

Но даже если п.4 не верен, должен же быть способ указать systemd читать мой .profile?

sdorof
() автор топика
Ответ на: комментарий от sdorof

зачем ему какие-то .profile ?? это заморочки юзверского шелла.
системд не использует баш или любой другой логин-шелл в принципе, проги запускает напрямую из-под себя.
припиши необходимую переменную окружения внутри сервиса.

pfg ★★★★★
()
Последнее исправление: pfg (всего исправлений: 1)
Ответ на: комментарий от pfg
  1. Как правильнее всего прописать переменную PATH внутри сервиса?

  2. Можно ли прописать внутри сервиса, чтобы пользовательские сервисы запускались в пользовательском окружении - в какой файл надо положить source ~/.profile?

sdorof
() автор топика

man environment.d

DESCRIPTION The environment.d directories contain a list of environment variable assignments for services started by the systemd user instance. systemd-environment-d-generator(8) parses them and updates the environment exported by the systemd user instance. See below for an discussion of which processes inherit those variables.

 It is recommended to use numerical prefixes for file names to simplify ordering.
  For backwards compatibility, a symlink to /etc/environment is installed, so this file is also parsed.

Оно?

her_s_gory
()
Последнее исправление: her_s_gory (всего исправлений: 1)

Комментирующие упускают из виду, что способ работал до обновления юбунтны.

это работало (по крайней мере, я не помню, чтобы приходилось перезапускать сервис вручную), пока недавно не обновил бубунту.

А во-вторых, способ из шапки темы, не только рабочий, но и прописан в арчвики, https://wiki.archlinux.org/title/Systemd/User#PATH.

krasnh ★★★★
()
Ответ на: комментарий от sdorof

если хочется, чтобы переменные окружения попадали и в консоль, и в systemd, то лучше всего прописывать их в ~/.pam_environment

Lrrr ★★★★★
()
Ответ на: комментарий от sdorof

2 нахера весь бардак из юзверского окружения тянуть в сервис ??
«разделяй и властвуй» - бросай ентое виндовое разгильдяйство :) в сервисе должно быть лишь то, что нужно конкретному сервису для его работы и ничего больше.

1 Environment= прописал необходимые параметры и океюшки.

pfg ★★★★★
()
Последнее исправление: pfg (всего исправлений: 3)

Это какая-то шляпа… куча мест, где задать можно, ни одного - где нужно…

Во-первых, в .profile отключаем импорт PATH в systemd и перезагружаем систему.

После загрузки, получаем PID emacs.service и выводим окружение:

systemctl --user status emacs
sudo strings /proc/<PID>/environ

Это окружение выглядит так (т.е. сразу после старта системы):

HOME=/home/user
LANG=ru_RU.UTF-8
LOGNAME=user
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin
SHELL=/bin/bash
SYSTEMD_EXEC_PID=2211
USER=user
XDG_DATA_DIRS=/home/user/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share/:/usr/share/:/var/lib/snapd/desktop
XDG_RUNTIME_DIR=/run/user/1000
GTK_MODULES=gail:atk-bridge
QT_ACCESSIBILITY=1
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
NOTIFY_SOCKET=/run/user/1000/systemd/notify
MANAGERPID=2203
INVOCATION_ID=17db45fe2a56471db4c642e07870b1e2
JOURNAL_STREAM=8:32296

Допустим, это минимальный набор необходимых переменных для запуска каждого сервиса, и XDG_DATA_DIRS, который задан вообще-то в .profile, импортуриуется в systemd, потому что systemd так хочет, а PATH, который задан там же, не импортируется, потому что systemd не хочет. Ок.

Запускаем командную строку и перезапускаем сервис, после чего окружение начинает выглядеть так:

HOME=/home/user
LANG=ru_RU.UTF-8
LOGNAME=user
PATH=/home/user/.pyenv/shims:/home/user/.pyenv/bin:/home/user/.local/bin:/home/user/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin
SHELL=/bin/bash
SYSTEMD_EXEC_PID=48263
USER=user
XDG_DATA_DIRS=/home/user/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/share/ubuntu:/home/user/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share/:/usr/share/:/var/lib/snapd/desktop
XDG_RUNTIME_DIR=/run/user/1000
GTK_MODULES=gail:atk-bridge
QT_ACCESSIBILITY=1
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
DESKTOP_SESSION=ubuntu
DISPLAY=:0
GDMSESSION=ubuntu
GNOME_DESKTOP_SESSION_ID=this-is-deprecated
GNOME_SETUP_DISPLAY=:1
GNOME_SHELL_SESSION_MODE=ubuntu
IM_CONFIG_PHASE=1
LANGUAGE=ru
LC_ADDRESS=ru_RU.UTF-8
LC_IDENTIFICATION=ru_RU.UTF-8
LC_MEASUREMENT=ru_RU.UTF-8
LC_MONETARY=ru_RU.UTF-8
LC_NAME=ru_RU.UTF-8
LC_NUMERIC=ru_RU.UTF-8
LC_PAPER=ru_RU.UTF-8
LC_TELEPHONE=ru_RU.UTF-8
LC_TIME=ru_RU.UTF-8
PAPERSIZE=a4
PWD=/home/user
PYENV_ROOT=/home/user/.pyenv
PYENV_SHELL=bash
QT_IM_MODULE=ibus
SESSION_MANAGER=local/comp:@/tmp/.ICE-unix/2501,unix/comp:/tmp/.ICE-unix/2501
SHLVL=0
SSH_AGENT_LAUNCHER=gnome-keyring
SSH_AUTH_SOCK=/run/user/1000/keyring/ssh
USERNAME=user
WAYLAND_DISPLAY=wayland-0
XAUTHORITY=/run/user/1000/.mutter-Xwaylandauth.ATPKR1
XDG_CONFIG_DIRS=/etc/xdg/xdg-ubuntu:/etc/xdg
XDG_CURRENT_DESKTOP=ubuntu:GNOME
XDG_MENU_PREFIX=gnome-
XDG_SESSION_CLASS=user
XDG_SESSION_DESKTOP=ubuntu
XDG_SESSION_TYPE=wayland
XMODIFIERS=@im=ibus
_=/usr/bin/gnome-session
NOTIFY_SOCKET=/run/user/1000/systemd/notify
MANAGERPID=2203
INVOCATION_ID=60674f2047144285b880f26abe9c33bb
JOURNAL_STREAM=8:206696

Как видно, тут уже собрано много больше, в том числе, мой PATH с питоном, и тот же .pam_environment,

LANGUAGE=ru
LANG=ru_RU.UTF-8
LC_NUMERIC=ru_RU.UTF-8
LC_TIME=ru_RU.UTF-8
LC_MONETARY=ru_RU.UTF-8
LC_PAPER=ru_RU.UTF-8
LC_NAME=ru_RU.UTF-8
LC_ADDRESS=ru_RU.UTF-8
LC_TELEPHONE=ru_RU.UTF-8
LC_MEASUREMENT=ru_RU.UTF-8
LC_IDENTIFICATION=ru_RU.UTF-8
PAPERSIZE=a4

которого на первом листинге почему-то нет.

Вопрос:

  1. где здесь «чистое окружение», в котором якобы запускается каждый сервис?
  2. почему переменные из .pam_environment не присутствуют в первом листинге?
  3. где и как, всё-таки, задавать PATH?
sdorof
() автор топика
Ответ на: комментарий от Lrrr

~/.pam_environment

С некоторых пор это перестало работать в Федоре и Гноме по крайней мере.

У меня так:

$ cat ~/.config/environment.d/envvars.conf 
PATH=$PATH:$HOME/Applications/bin
PATH=$PATH:$HOME/.local/bin
VISUAL=nvim
EDITOR=nvim
STEAM_FRAME_FORCE_CLOSE=0
Im_not_a_robot ★★★★★
()
Ответ на: комментарий от Im_not_a_robot

Спасибо, заработало:

$ cat .config/environment.d/envvars.conf 
PATH=$HOME/.pyenv/shims:$HOME/.pyenv/bin:$PATH

при этом, из .profile путь убрал - в консоль также подтягивается из envvars

sdorof
() автор топика
Ответ на: комментарий от Im_not_a_robot

ах вот оно что! https://man.archlinux.org/man/pam_env.8

user_readenv=0|1

Due to problematic security this functionality is deprecated since the 1.5.0 version and will be removed completely at some point in the future

спасибо добрым дядям из федоры с гномом за то что заботятся о нашей безопасности, выпиливая фичи и ломая работающие сетапы :)))

Lrrr ★★★★★
()
Ответ на: комментарий от Lrrr

выпиливая фичи и ломая работающие сетапы

Ну так-то переменные через pam – это костылище и правильней использовать для этого systemd: ~/.config/environment.d. Другое дело что он с некоторыми переменными тоже через жопу работает, по крайней мере у меня так было, может уже починили, а может я просто неправильно что-то писал.

Im_not_a_robot ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.