у меня есть Система Arch Linux с systemd и я создал свой собственный сервис. Служба настройки по адресу /etc/systemd/system/myservice.service
выглядит так:
[Unit]
Description=My Daemon
[Service]
ExecStart=/bin/myforegroundcmd
[Install]
WantedBy=multi-user.target
Теперь я хочу установить переменную среды для /bin/myforegroundcmd
. Как я могу это сделать?
Времена меняются, и меняются лучшие практики.
В ток лучший способ сделать это - запустить systemctl edit myservice
, который создаст для вас файл переопределения или позволит вам отредактировать существующий.
В обычных установках это создаст каталог /etc/systemd/system/myservice.service.d
, и внутри этого каталога создайте файл, имя которого заканчивается на .conf
(обычно override.conf
), и в этом файле вы можете добавить или переопределить любую часть модуля, поставляемого дистрибутивом.
Например, в файле /etc/systemd/system/myservice.service.d/myenv.conf
:
[Service]
Environment="SECRET=pGNqduRFkB4K9C2vijOmUDa2kPtUhArN"
Environment="ANOTHER_SECRET=JP8YLOc2bsNlrGuD6LVTq7L36obpjzxd"
Также обратите внимание, что если каталог существует и пуст, ваша служба будет отключена! Если вы не собираетесь помещать что-либо в каталог, убедитесь, что этого не существует.
Для справки, старый способ был:
Рекомендуемый способ для этого нужно создать файл /etc/sysconfig/myservice
который содержит ваши переменные, а затем загрузите их с помощью EnvironmentFile
.
Для получения полной информации см. Документацию Fedora по как написать сценарий systemd.
Ответ зависит от того, должна ли переменная быть постоянной (т. Е. Не должна изменяться пользователем, получающим модуль) или переменной (предполагается, что она устанавливается пользователем).
Поскольку это ваша локальная единица, граница довольно размыта, и в любом случае будет работать. Однако, если вы начнете распространять его, и он окажется в /usr/lib/systemd/system
, это станет важным.
Если значение не нужно изменять для каждого экземпляра, предпочтительным способом было бы разместить его как Environment=
, прямо в файле модуля:
[Unit]
Description=My Daemon
[Service]
Environment="FOO=bar baz"
ExecStart=/bin/myforegroundcmd
[Install]
WantedBy=multi-user.target
Преимущество этого в том, что переменная хранится в одном файле с модулем. Таким образом, файл модуля легче перемещать между системами.
Однако вышеуказанное решение не работает, когда системный администратор должен изменить значение переменной среды локально. Более конкретно, новое значение нужно будет устанавливать каждый раз при обновлении файла модуля.
В этом случае следует использовать дополнительный файл. Как - обычно зависит от политики распространения.
Одно особенно интересное решение - использовать /etc/systemd/system/myservice.service.d
каталог. В отличие от других решений, этот каталог поддерживается самой системой systemd и поэтому не имеет путей для конкретных дистрибутивов.
В этом случае вы помещаете файл вроде /etc/systemd/system/myservice.service.d/local.conf
который добавляет недостающие части файла модуля:
[Service]
Environment="FOO=bar baz"
После этого systemd объединяет два файла при запуске службы (не забудьте systemctl daemon-reload
после изменения любого из них). И поскольку этот путь используется непосредственно systemd, вы не используете EnvironmentFile=
для этого.
Если предполагается, что значение должно быть изменено только в некоторых из затронутых систем, вы можете объединить оба решения, предоставив значение по умолчанию непосредственно в модуле и локальное переопределение в другом файле.
http://0pointer.de/public/systemd-man/systemd.exec.html#Environment= - у вас есть два варианта (один уже указал Майкл):
Environment=
и
EnvironmentFile=
Ответы Майкл и Михал полезны и отвечают на исходный вопрос о том, как установить переменную среды для службы systemd. Однако один общего пользования для переменных среды заключается в настройке конфиденциальных данных, таких как пароли, в месте, которое случайно не будет передано в систему управления версиями с кодом вашего приложения.
Если именно поэтому вы хотите передать в службу переменную среды, не использовать Environment=
в файле конфигурации устройства. Использовать EnvironmentFile=
и укажите в нем другой файл конфигурации, доступный для чтения только учетной записи службы (и пользователям с правами root).
Подробности файла конфигурации устройства видны любому пользователю с помощью этой команды:
systemctl show my_service
Я поместил файл конфигурации в /etc/my_service/my_service.conf
и вложил туда свои секреты:
MY_SECRET=correcthorsebatterystaple
Затем в моем файле служебной единицы я использовал EnvironmentFile=
:
[Unit]
Description=my_service
[Service]
ExecStart=/usr/bin/python /path/to/my_service.py
EnvironmentFile=/etc/my_service/my_service.conf
User=myservice
[Install]
WantedBy=multi-user.target
Я проверил это ps auxe
не может видеть эти переменные среды, а другие пользователи не имеют доступа к /proc/*/environ
. Конечно, проверьте свою систему.
Майкл дал одно чистое решение, но я хотел получить обновленную переменную env из скрипта. К сожалению, выполнение команд bash невозможно в файле модуля systemd. К счастью, вы можете запустить bash внутри ExecStart:
http://www.dsm.fordham.edu/cgi-bin/man-cgi.pl?topic=systemd.service&sect=5
Обратите внимание, что этот параметр не поддерживает напрямую командные строки оболочки. Если должны использоваться командные строки оболочки, их необходимо явно передать какой-либо реализации оболочки.
Пример в нашем случае:
[Service]
ExecStart=/bin/bash -c "ENV=`script`; /bin/myforegroundcmd"