Hacer que el servicio systemd herede variables de entorno de /etc/profile.d

Hacer que el servicio systemd herede variables de entorno de /etc/profile.d

Tengo un systemdservicio ejecutándose bajo un usuario específico.

Supuse erróneamente que el servicio tendría acceso a las variables de entorno que todos los usuarios heredan de los scripts/exportaciones en/etc/profile.d

¿Hay alguna manera de lograr esto sin tener que copiar manualmente las variables en systemdla definición del archivo unitario?

Por ejemplo, tengo lo siguiente

$ cat /etc/profile.d/somexports

export VAR1=VALUE1
export VAR2=VALUE2

¿Se puede pasar/exportar esto a un systemdservicio?

Respuesta1

Hay algunas posibles fuentes de medio ambiente:

  1. Usando Environment=el cual te permite establecer variables
  2. Usar EnvironmentFile=el cual te permite cargar valores desde un archivo
  3. Su uso PassEnvironment=le permite definir variables que deben pasarse desde PID1.
  4. Configuración estática (p. ej $USER.)

Puede parecer que EnvironmentFile=/etc/profile.d/someexportses lo que quieres, pero no es así. /etc/profile.d/*a menudo proviene de su shell y puede ser analizado por su shell. systemdes independiente del shell y, por lo tanto, no dependerá de la sintaxis de bash. Debe EnvironmentFilecontener asignaciones de variables separadas por nuevas líneas, lo cual es mucho más estricto.

systemdEl diseño desalienta el cambio dinámico de unidades o sus entornos. Incluso la opción se añadió sólo como resultado de la presión y luego los desarrolladores EnvironmentFile=la consideraron un error . systemdUn ejemplo de este diseño es que $PATHno afecta qué binarios se utilizan. Esto hace que las cosas sean más deterministas, ya que cuando defines una unidad, estás definiendo todo acerca de cómo debe funcionar esa unidad sin preocuparte por la influencia externa.

La respuesta corta es: No. No puedes cargar /etc/profile.d/*y systemdeso es intencional.

Pero la respuesta que probablemente quieras es: sí, puedes cargarlo. Sólo necesita ejecutar su aplicación a través de un shell.

Puedes hacerlo cambiando:

ExecStart=/usr/bin/myservice

A

ExecStart=/usr/bin/bash -lc myservice

Eso hará bashque sea el proceso padre, el que carga /etc/profile.d/y reenvía ese entorno a su hijo. También tenga en cuenta que no especificé una ruta absoluta completa a myservice. En este caso, myservicese basará en $PATHy eso puede ser o no /usr/bin/myservice. Puede ver cómo esto puede hacer que las cosas sean más difíciles de solucionar y esa es la desventaja de seguir este camino.

Respuesta2

Creo que esto se aborda de la siguiente manera.

ExecStart=/bin/sh -lc /path/to/binary

La -lbandera convierte la invocación del shell en un shell de inicio de sesión. Necesitamos esto porque solo los shells de inicio de sesión generan scripts de perfil.

$ bash --help | grep -- -l
GNU bash, version 4.4.12(1)-release-(x86_64-pc-linux-gnu)
    --login

información relacionada