У меня есть systemd
служба, запущенная под определенным пользователем.
Я ошибочно предположил, что служба будет иметь доступ к переменным среды, которые все пользователи наследуют из скриптов/экспортов в/etc/profile.d
Есть ли способ сделать это без необходимости вручную копировать переменные в systemd
определении файла модуля?
Например, у меня есть следующее
$ cat /etc/profile.d/somexports
export VAR1=VALUE1
export VAR2=VALUE2
Можно ли это передать/экспортировать в systemd
службу?
решение1
Существует несколько возможных источников окружающей среды:
- Использование
Environment=
which позволяет вам устанавливать переменные - Использование
EnvironmentFile=
которого позволяет загружать значения из файла - Использование
PassEnvironment=
which позволяет определить переменные, которые следует передать из 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