systemd 서비스가 /etc/profile.d의 환경 변수를 상속하도록 합니다.

systemd 서비스가 /etc/profile.d의 환경 변수를 상속하도록 합니다.

systemd특정 사용자로 실행되는 서비스가 있습니다 .

서비스가 스크립트/내보내기에서 모든 사용자의 상속된 환경 변수에 액세스할 수 있다고 잘못 생각했습니다./etc/profile.d

systemd유닛 파일 정의에서 변수를 수동으로 복사하지 않고 이를 수행할 수 있는 방법이 있습니까?

예를 들어, 다음이 있습니다.

$ cat /etc/profile.d/somexports

export VAR1=VALUE1
export VAR2=VALUE2

systemd이를 서비스 에 전달/내보낼 수 있나요 ?

답변1

여러 가지 가능한 환경 소스가 있습니다.

  1. Environment=변수를 설정하는데 사용하세요
  2. EnvironmentFile=파일에서 값을 로드하려면 이를 사용합니다 .
  3. 이를 사용하면 PassEnvironment=PID1에서 전달되어야 하는 변수를 정의할 수 있습니다.
  4. 정적 구성(예 $USER: )

이는 EnvironmentFile=/etc/profile.d/someexports귀하가 원하는 것처럼 들릴 수도 있지만 그렇지 않습니다. /etc/profile.d/*일반적으로 쉘에서 얻고 구문 분석할 수 있습니다. systemd쉘에 구애받지 않으므로 bash 구문에 의존하지 않습니다. EnvironmentFile더 엄격한 개행 구분 변수 할당을 포함 해야 합니다 .

systemd설계는 장치나 환경에 대한 동적 변경을 방지합니다. 이 EnvironmentFile=옵션조차도 압력을 받아 추가되었으며 나중에 systemd개발자는 실수로 간주했습니다. 이 디자인의 예는 $PATH사용되는 바이너리에 영향을 주지 않는다는 것입니다. 이는 단위를 정의할 때 외부 영향에 대해 걱정하지 않고 단위가 어떻게 작동해야 하는지에 대한 모든 것을 정의하기 때문에 상황을 더욱 결정적으로 만듭니다.

따라서 짧은 대답은 다음과 같습니다. 아니요. 로드할 수 없습니다 /etc/profile.d/*. systemd이는 의도적인 것입니다.

하지만 아마도 여러분이 원하는 대답은 다음과 같습니다. 예, 로드할 수 있습니다. 셸을 통해 애플리케이션을 실행하기만 하면 됩니다.

다음을 변경하여 이를 수행할 수 있습니다.

ExecStart=/usr/bin/myservice

도착하다

ExecStart=/usr/bin/bash -lc myservice

그러면 bash상위 프로세스가 해당 환경을 로드 /etc/profile.d/하고 이를 하위 프로세스로 전달하게 됩니다. 또한 전체 절대 경로를 지정하지 않았습니다 myservice. 이 경우 는 을 myservice기반으로 하며 $PATH가 될 수도 있고 아닐 수도 있습니다 /usr/bin/myservice. 이로 인해 문제 해결이 더 어려워질 수 있으며 이는 이 접근 방식의 단점입니다.

답변2

이 문제는 다음과 같이 해결될 수 있다고 생각합니다

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

-l플래그는 쉘 호출을 로그인 쉘로 만듭니다. 로그인 셸 소스 프로필 스크립트만 있기 때문에 이것이 필요합니다.

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

관련 정보