Eu tenho um systemd
serviço em execução sob um usuário específico.
Presumi erroneamente que o serviço teria acesso às variáveis de ambiente que todos os usuários herdam de scripts/exportações em/etc/profile.d
Existe uma maneira de fazer isso sem precisar copiar manualmente as variáveis na systemd
definição do arquivo de unidade.
Por exemplo, tenho o seguinte
$ cat /etc/profile.d/somexports
export VAR1=VALUE1
export VAR2=VALUE2
Isso pode ser passado/exportado para um systemd
serviço?
Responder1
Existem algumas fontes possíveis de ambiente:
- Usar
Environment=
which permite definir variáveis - Usar
EnvironmentFile=
which permite carregar valores de um arquivo - Usar
PassEnvironment=
which permite definir variáveis que devem ser passadas do PID1. - Configuração estática (por exemplo
$USER
)
Pode parecer que EnvironmentFile=/etc/profile.d/someexports
é o que você deseja, mas não é o caso. /etc/profile.d/*
geralmente é originado pelo seu shell e pode ser analisado pelo seu shell. systemd
é independente do shell e, portanto, não dependerá da sintaxe do bash. Deve EnvironmentFile
conter atribuições de variáveis separadas por nova linha, o que é muito mais rigoroso.
systemd
O design desencoraja a mudança dinâmica de unidades ou de seus ambientes. Mesmo a EnvironmentFile=
opção só foi adicionada por pressão e mais tarde foi considerada um erro pelos systemd
desenvolvedores do . Um exemplo desse design é que $PATH
não afeta quais binários são usados. Isso mantém as coisas mais determinísticas, pois quando você define uma unidade, você está definindo tudo sobre como essa unidade deve funcionar sem se preocupar com influências externas.
A resposta tão curta é: Não. você não pode carregar /etc/profile.d/*
e systemd
isso é intencional.
Mas a resposta que você provavelmente deseja é: sim, você pode carregá-lo. Você só precisa executar seu aplicativo através de um shell.
Você pode fazer isso alterando:
ExecStart=/usr/bin/myservice
Para
ExecStart=/usr/bin/bash -lc myservice
Isso fará com bash
que seja o processo pai, que carrega /etc/profile.d/
e encaminha esse ambiente para seu filho. Observe também que não especifiquei um caminho absoluto completo para myservice
. Neste caso, myservice
será baseado em $PATH
e isso pode ou não ser /usr/bin/myservice
. Você pode ver como isso pode tornar as coisas mais difíceis de solucionar e essa é a desvantagem de seguir esse caminho.
Responder2
Eu acho que isso é abordado da seguinte maneira
ExecStart=/bin/sh -lc /path/to/binary
O -l
sinalizador torna a invocação do shell um shell de login. Precisamos disso porque apenas os scripts de perfil de origem dos shells de login.
$ bash --help | grep -- -l
GNU bash, version 4.4.12(1)-release-(x86_64-pc-linux-gnu)
--login