AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 413397
Accepted
lfagundes
lfagundes
Asked: 2012-08-02 11:43:04 +0800 CST2012-08-02 11:43:04 +0800 CST 2012-08-02 11:43:04 +0800 CST

如何在systemd服务中设置环境变量?

  • 772

我有一个带有 systemd 的 Arch Linux 系统,我已经创建了自己的服务。配置服务/etc/systemd/system/myservice.service看起来像这样:

[Unit]
Description=My Daemon

[Service]
ExecStart=/bin/myforegroundcmd

[Install]
WantedBy=multi-user.target

现在我想为/bin/myforegroundcmd. 我怎么做?

systemd
  • 6 6 个回答
  • 507967 Views

6 个回答

  • Voted
  1. Best Answer
    Michael Hampton
    2012-08-02T12:07:49+08:002012-08-02T12:07:49+08:00

    时代在变,最佳实践也在变。

    当前执行此操作的最佳方法是运行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 脚本的文档。

    • 414
  2. Michał Górny
    2014-04-23T23:48:47+08:002014-04-23T23:48:47+08:00

    答案取决于变量是应该是常量(也就是说,不应该由用户获取单位来修改)还是变量(应该由用户设置)。

    由于它是您的本地单位,因此边界非常模糊,任何一种方式都可以。但是,如果您开始分发它并且它​​最终会在 中/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=为此使用。

    如果该值应该只在某些受影响的系统上更改,您可以结合这两种解决方案,直接在单元中提供默认值,并在其他文件中提供本地覆盖。

    • 115
  3. paluh
    2012-10-17T05:55:37+08:002012-10-17T05:55:37+08:00

    http://0pointer.de/public/systemd-man/systemd.exec.html#Environment= - 你有两个选择(迈克尔已经指出了一个):

    Environment=
    

    和

    EnvironmentFile=
    
    • 54
  4. Don Kirkby
    2018-05-04T16:29:13+08:002018-05-04T16:29:13+08:00

    Michael和Michał的回答很有帮助,并回答了如何为 systemd 服务设置环境变量的原始问题。但是,环境变量的一个常见用途是在一个不会意外提交给应用程序代码的源代码控制的地方配置敏感数据(如密码)。

    如果这就是你想要将环境变量传递给你的服务的原因,请不要Environment=在单元配置文件中使用。使用EnvironmentFile=并将其指向另一个配置文件,该文件只能由服务帐户(以及具有根访问权限的用户)读取。

    使用此命令的任何用户都可以看到单元配置文件的详细信息:

    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. 当然,请检查您自己的系统。

    • 46
  5. user1830432
    2014-07-24T05:31:47+08:002014-07-24T05:31:47+08:00

    迈克尔给出了一个干净的解决方案,但我想从脚本中获取更新的环境变量。不幸的是,在 systemd 单元文件中无法执行 bash 命令。幸运的是,您可以在 ExecStart 中触发 bash:

    http://www.dsm.fordham.edu/cgi-bin/man-cgi.pl?topic=systemd.service&sect=5

    请注意,此设置不直接支持 shell 命令行。如果要使用 shell 命令行,则需要将它们显式传递给某种 shell 实现。

    在我们的案例中,示例是:

    [Service]
    ExecStart=/bin/bash -c "ENV=`script`; /bin/myforegroundcmd"
    
    • 11
  6. Adrnalnrsh
    2022-09-10T09:25:27+08:002022-09-10T09:25:27+08:00

    不要将 Environment= 或 EnvironmentFile= 用于凭据/机密。

    根据https://www.freedesktop.org/software/systemd/man/systemd.exec.html#Environment

    你应该使用LoadCredential=, LoadCredentialEncrypted= or SetCredentialEncrypted=

    请注意,环境变量不适合将秘密(例如密码、密钥材料……)传递给服务进程。为单元设置的环境变量通过 D-Bus IPC 暴露给非特权客户端,通常不被理解为需要保护的数据。此外,环境变量沿着进程树向下传播,包括跨越安全边界(例如 setuid/setgid 可执行文件),因此可能会泄漏到不应访问秘密数据的进程。使用 LoadCredential=、LoadCredentialEncrypted= 或 SetCredentialEncrypted=(见下文)将数据安全地传递到单元进程。

    • 0

相关问题

  • 将 shell 脚本置于 systemd 控制之下

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve