Заставить службу 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=which позволяет вам устанавливать переменные
  2. Использование EnvironmentFile=которого позволяет загружать значения из файла
  3. Использование PassEnvironment=which позволяет определить переменные, которые следует передать из 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

Связанный контент