Faça o serviço systemd herdar variáveis ​​de ambiente de /etc/profile.d

Faça o serviço systemd herdar variáveis ​​de ambiente de /etc/profile.d

Eu tenho um systemdserviç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 systemddefiniçã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 systemdserviço?

Responder1

Existem algumas fontes possíveis de ambiente:

  1. Usar Environment=which permite definir variáveis
  2. Usar EnvironmentFile=which permite carregar valores de um arquivo
  3. Usar PassEnvironment=which permite definir variáveis ​​​​que devem ser passadas do PID1.
  4. 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 EnvironmentFileconter atribuições de variáveis ​​separadas por nova linha, o que é muito mais rigoroso.

systemdO 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 systemddesenvolvedores do . Um exemplo desse design é que $PATHnã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 systemdisso é 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 bashque 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, myserviceserá baseado em $PATHe 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 -lsinalizador 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

informação relacionada