我有一个带有 systemd 的 Arch Linux 系统,我已经创建了自己的服务。配置服务/etc/systemd/system/myservice.service
看起来像这样:
[Unit]
Description=My Daemon
[Service]
ExecStart=/bin/myforegroundcmd
[Install]
WantedBy=multi-user.target
现在我想为/bin/myforegroundcmd
. 我怎么做?
我有一个带有 systemd 的 Arch Linux 系统,我已经创建了自己的服务。配置服务/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
:另请注意,如果该目录存在且为空,您的服务将被禁用!如果您不打算在目录中放置某些内容,请确保它不存在。
作为参考,旧方法是:
推荐的方法是创建一个
/etc/sysconfig/myservice
包含变量的文件,然后使用EnvironmentFile
.有关完整的详细信息,请参阅 Fedora 关于如何编写 systemd 脚本的文档。
答案取决于变量是应该是常量(也就是说,不应该由用户获取单位来修改)还是变量(应该由用户设置)。
由于它是您的本地单位,因此边界非常模糊,任何一种方式都可以。但是,如果您开始分发它并且它最终会在 中
/usr/lib/systemd/system
,那么这将变得很重要。常数值
如果每个实例的值不需要更改,首选方法是将其作为
Environment=
, 直接放在单元文件中:这样做的好处是变量与单元保存在一个文件中。因此,单元文件更容易在系统之间移动。
变量值
但是,当系统管理员应该在本地更改环境变量的值时,上述解决方案并不适用。更具体地说,每次更新单元文件时都需要设置新值。
对于这种情况,将使用一个额外的文件。如何——通常取决于分配策略。
一个特别有趣的解决方案是使用
/etc/systemd/system/myservice.service.d
目录。与其他解决方案不同,此目录由 systemd 本身支持,因此没有特定于发行版的路径。在这种情况下,您放置一个文件,这样
/etc/systemd/system/myservice.service.d/local.conf
可以添加单元文件的缺失部分:之后,systemd 在启动服务时合并这两个文件(记住
systemctl daemon-reload
在更改其中任何一个之后)。由于此路径由 systemd 直接使用,因此您不会EnvironmentFile=
为此使用。如果该值应该只在某些受影响的系统上更改,您可以结合这两种解决方案,直接在单元中提供默认值,并在其他文件中提供本地覆盖。
http://0pointer.de/public/systemd-man/systemd.exec.html#Environment= - 你有两个选择(迈克尔已经指出了一个):
和
Michael和Michał的回答很有帮助,并回答了如何为 systemd 服务设置环境变量的原始问题。但是,环境变量的一个常见用途是在一个不会意外提交给应用程序代码的源代码控制的地方配置敏感数据(如密码)。
如果这就是你想要将环境变量传递给你的服务的原因,请不要
Environment=
在单元配置文件中使用。使用EnvironmentFile=
并将其指向另一个配置文件,该文件只能由服务帐户(以及具有根访问权限的用户)读取。使用此命令的任何用户都可以看到单元配置文件的详细信息:
我放了一个配置文件
/etc/my_service/my_service.conf
并把我的秘密放在那里:然后在我的服务单元文件中,我使用了
EnvironmentFile=
:我检查了
ps auxe
看不到那些环境变量,其他用户无权访问/proc/*/environ
. 当然,请检查您自己的系统。迈克尔给出了一个干净的解决方案,但我想从脚本中获取更新的环境变量。不幸的是,在 systemd 单元文件中无法执行 bash 命令。幸运的是,您可以在 ExecStart 中触发 bash:
http://www.dsm.fordham.edu/cgi-bin/man-cgi.pl?topic=systemd.service§=5
在我们的案例中,示例是:
不要将 Environment= 或 EnvironmentFile= 用于凭据/机密。
根据https://www.freedesktop.org/software/systemd/man/systemd.exec.html#Environment
你应该使用
LoadCredential=, LoadCredentialEncrypted= or SetCredentialEncrypted=