systemd
특정 사용자로 실행되는 서비스가 있습니다 .
서비스가 스크립트/내보내기에서 모든 사용자의 상속된 환경 변수에 액세스할 수 있다고 잘못 생각했습니다./etc/profile.d
systemd
유닛 파일 정의에서 변수를 수동으로 복사하지 않고 이를 수행할 수 있는 방법이 있습니까?
예를 들어, 다음이 있습니다.
$ cat /etc/profile.d/somexports
export VAR1=VALUE1
export VAR2=VALUE2
systemd
이를 서비스 에 전달/내보낼 수 있나요 ?
답변1
여러 가지 가능한 환경 소스가 있습니다.
Environment=
변수를 설정하는데 사용하세요EnvironmentFile=
파일에서 값을 로드하려면 이를 사용합니다 .- 이를 사용하면
PassEnvironment=
PID1에서 전달되어야 하는 변수를 정의할 수 있습니다. - 정적 구성(예
$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