
Eu tenho uma necessidade simples de executar um serviço de usuário systemd com acesso a todas as variáveis de ambiente fornecidas pela sessão DBus do usuário. Aqui está minha unidade de exemplo:
[Unit]
Description=Environment Demo
[Service]
Type=simple
Environment=DISPLAY=:0
ExecStart=/bin/bash -c 'env > shell.env.sh'
Restart=on-failure
RestartSec=5s
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=default.target
As chaves exportadas são:
_
DISPLAY
HOME
LANG
LOGNAME
MANAGERPID
PATH
PWD
SHELL
SHLVL
USER
XDG_RUNTIME_DIR
Isso está muito longe da lista completa de variáveis de ambiente presentes se eu iniciar um aplicativo de desktop da minha bandeja ou do meu inicializador (estou no sistema operacional elementar Loki, também conhecido como Ubuntu 16.04 xenial). Se eu iniciar meu emulador de terminal ( pantheon-terminal
) e obtiver uma lista ordenada de minhas variáveis de ambiente, obtenho o seguinte:
_
DBUS_SESSION_BUS_ADDRESS
DEFAULTS_PATH
DESKTOP_SESSION
DISPLAY
EDITOR
GDM_LANG
GDMSESSION
GIO_LAUNCHED_DESKTOP_FILE
GIO_LAUNCHED_DESKTOP_FILE_PID
GNOME_DESKTOP_SESSION_ID
GPG_TTY
GSETTINGS_SCHEMA_DIR
GTK_CSD
GTK_MODULES
HOME
LANG
LANGUAGE
LESSCLOSE
LESSOPEN
LOGNAME
LS_COLORS
MANDATORY_PATH
PANTHEON_TERMINAL_ID
PATH
PROMPT_COMMAND
PWD
QT_ACCESSIBILITY
QT_IM_MODULE
QT_LINUX_ACCESSIBILITY_ALWAYS_ON
QT_STYLE_OVERRIDE
SESSION_MANAGER
SHELL
SHLVL
SSH_AGENT_PID
SSH_AUTH_SOCK
TERM
USER
VTE_VERSION
XAUTHORITY
XDG_CONFIG_DIRS
XDG_CURRENT_DESKTOP
XDG_DATA_DIRS
XDG_GREETER_DATA_DIR
XDG_MENU_PREFIX
XDG_RUNTIME_DIR
XDG_SEAT
XDG_SEAT_PATH
XDG_SESSION_DESKTOP
XDG_SESSION_ID
XDG_SESSION_PATH
XDG_SESSION_TYPE
XDG_VTNR
XMODIFIERS
Para deixar as coisas mais claras:
diff --git a/systemd-user.env.txt b/pantheon-terminal.env.txt
index c684056..f6d0685 100644
--- a/systemd-user.env.txt
+++ b/pantheon-terminal.env.txt
@@ -1,12 +1,54 @@
_
+DBUS_SESSION_BUS_ADDRESS
+DEFAULTS_PATH
+DESKTOP_SESSION
DISPLAY
+EDITOR
+GDM_LANG
+GDMSESSION
+GIO_LAUNCHED_DESKTOP_FILE
+GIO_LAUNCHED_DESKTOP_FILE_PID
+GNOME_DESKTOP_SESSION_ID
+GPG_TTY
+GSETTINGS_SCHEMA_DIR
+GTK_CSD
+GTK_MODULES
HOME
LANG
+LANGUAGE
+LESSCLOSE
+LESSOPEN
LOGNAME
-MANAGERPID
+LS_COLORS
+MANDATORY_PATH
+PANTHEON_TERMINAL_ID
PATH
+PROMPT_COMMAND
PWD
+QT_ACCESSIBILITY
+QT_IM_MODULE
+QT_LINUX_ACCESSIBILITY_ALWAYS_ON
+QT_STYLE_OVERRIDE
+SESSION_MANAGER
SHELL
SHLVL
+SSH_AGENT_PID
+SSH_AUTH_SOCK
+TERM
USER
+VTE_VERSION
+XAUTHORITY
+XDG_CONFIG_DIRS
+XDG_CURRENT_DESKTOP
+XDG_DATA_DIRS
+XDG_GREETER_DATA_DIR
+XDG_MENU_PREFIX
XDG_RUNTIME_DIR
+XDG_SEAT
+XDG_SEAT_PATH
+XDG_SESSION_DESKTOP
+XDG_SESSION_ID
+XDG_SESSION_PATH
+XDG_SESSION_TYPE
+XDG_VTNR
+XMODIFIERS
Existem cerca de mais 30 variáveis de ambiente ao iniciar algo dessa maneira.
Meu caso de uso é este: quero poder iniciar processos com um ambiente completo, como no contexto de inicialização do meu aplicativo de terminal.
Como posso expor um ambiente completo aos meus daemons de usuário do systemd?
Responder1
Você pode encontrar alguma ajuda noPágina wiki do ArchLinuxque discute a configuração do ambiente para unidades de usuário. Em particular,
systemctl --user import-environment
exportará todas as variáveis de ambiente atuais para o ambiente de usuário do systemd. Você pode fornecer uma lista explícita de variáveis. Você pode verificar executando
systemctl --user show-environment
antes e depois. Há também
systemctl --user set-environment MYVAR=myvalue ...
systemctl --user unset-environment MYVAR ...
Veja a systemctl
página de manual. O wiki também menciona uma alternativa específica do dbus com a qual tive menos sucesso:
dbus-update-activation-environment --systemd --all
Responder2
Minha solução leva em consideração a solução do @meuh acima e algumas pesquisas.
O primeiro passo é criar uma unidade de usuário fictícia chamada dbus-environment.service
:
[Unit]
Description=Environment Imported Target
[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/bin/true
O próximo passo é criar um script Bash:
#!/bin/bash
systemctl --user import-environment
systemctl --user start dbus-environment.service
Em seguida, adicione este script aos aplicativos de inicialização do seu gerenciador de janelas que têm garantia de execução na sessão DBUS e no gerenciador de janelas, X, etc.
No login da sessão, o script será chamado, importando tudo para o daemon do usuário systemd.
Em seguida, para todas as unidades que dependem dessas variáveis de ambiente, basta fazer com que elas dependam de dbus-environment.service
:
[Unit]
Description=Duplicity Backup Service
Requires=dbus-environment.service
After=dbus-environment.service
[Service]
Type=oneshot
ExecStart=/home/naftuli/.local/bin/duply home backup
Neste ponto, ao iniciar este serviço, é garantido que o ambiente será importado. Talvez eu devesse usar um alvo em vez de um serviço, mas esse exercício terá de esperar.
Responder3
@Naftuli: Não teria sido melhor usar algo assim em todos os arquivos da sua unidade de serviços?
ExecStartPre=\usr\bin\sh -c "systemctl --user import-environment"