如何让systemd变量在重启后保留?

8

我有一个由第三方供应商提供的产品。它包括许多服务,供应商提供initd风格的启动脚本,每个服务都有一个相应的脚本。

这些脚本引用变量,例如JAVA_HOME,THE_PRODUCT_HOME等。供应商的期望是我必须手动编辑这些脚本并硬编码正确的值。我更希望这些变量从系统启动时从systemd获取的环境变量中初始化。

我知道我可以为每个服务创建一个重载配置文件,使用systemctl edit theService来提供必要的环境变量,但是:

  1. 有相当多的启动脚本
  2. 基本变量都是相同的
  3. 如果可能的话,我想避免“systemctl edit”每个提供的脚本

到目前为止,我尝试过使用systemctl set-environment VAR_NAME=some_value

这完美地解决了问题-直到我重新启动系统。看起来设置的这些变量是全局定义的,但在重新启动后不会保存。我也尝试过使用systemctl daemon-reload以防需要“提交”设置(但似乎它没有保存全局环境变量)。

目前,我已经编辑了每一个提供的启动脚本,并执行source /path/to/theGlobalVariablesINeed.sh

这个解决方法可以作为一个"workaround",但不是我未来的首选解决方案...

下面是正在发生的情况的说明:

定义一些变量

[root@dav1-td1 -> ~] # systemctl show-environment
LANG=en_US.UTF-8
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
[root@dav1-td1 -> ~] #

[root@dav1-td1 -> ~] # systemctl set-environment SYSD_PRODNAME_JAVA_HOME=/usr/java/jdk1.8.0_181-amd64/jre
[root@dav1-td1 -> ~] # systemctl set-environment SYSD_PRODNAME_HOME=/opt/TheProduct-1.2.3
[root@dav1-td1 -> ~] # systemctl daemon-reload        # This is optional, if I run the reload, or do not run the reload, the variables are still lost over a reboot.

展示变量已经被设置。
#### Now some variables are set, If I restart a service, the service will
#### Pick up these environmental variable settings.

[root@dav1-td1 -> ~] # systemctl show-environment
LANG=en_US.UTF-8
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
SYSD_PRODNAME_HOME=/opt/TheProduct-1.2.3
SYSD_PRODNAME_JAVA_HOME=/usr/java/jdk1.8.0_181-amd64/jre
[root@dav1-td1 -> ~] #

系统重启

#### After restart, the variables have disappeared !?!?

[root@dav1-td1 -> ~] # systemctl show-environment
LANG=en_US.UTF-8
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
[root@dav1-td1 -> ~] #

如上所述,当我重新启动系统时,使用systemctl set-environment VAR=value设置的任何环境变量都会丢失。

我需要这些变量在重启后保留(不使用每个服务覆盖文件且无需使用包含所有变量的文件作为源)。

1个回答

12

解决这个问题的方法有很多种。

1. 使用systemd配置设置环境变量

您可以编辑/lib/systemd/system/system.conf文件并添加以下内容:

[Manager]
DefaultEnvironment=A=B C=D

2. 使用另一个systemd服务来设置环境变量

[Unit]
Description=Example systemd service init

[Service]
Type=simple
ExecStart=/bin/systemctl set-environment VAR_NAME=some_value

[Install]
WantedBy=sysinit.target

重要的是使用WantedBy=sysinit.target,以便早期加载。

现在我们可以创建一个简单的服务来测试这一点。

[Unit]
Description=Example systemd service.

[Service]
Type=simple
ExecStart=/usr/bin/env

[Install]
WantedBy=multi-user.target

以及结果

root@vagrant:/lib/systemd/system# systemctl status tarun
● tarun.service - Example systemd service.
   Loaded: loaded (/lib/systemd/system/tarun.service; enabled; vendor preset: enabled)
   Active: inactive (dead) since Sat 2019-06-15 11:31:17 UTC; 5s ago
  Process: 1712 ExecStart=/usr/bin/env (code=exited, status=0/SUCCESS)
 Main PID: 1712 (code=exited, status=0/SUCCESS)

Jun 15 11:31:17 vagrant systemd[1]: Started Example systemd service..
Jun 15 11:31:17 vagrant env[1712]: A=B
Jun 15 11:31:17 vagrant env[1712]: C=D
Jun 15 11:31:17 vagrant env[1712]: LANG=en_US.UTF-8
Jun 15 11:31:17 vagrant env[1712]: PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
Jun 15 11:31:17 vagrant env[1712]: VAR_NAME=some_value

感谢@Tarun_Lalwani - 我简直不敢相信我花了几天时间阅读手册,搜索在线资料,尝试和错误才找到了一些本来应该很简单但是我却没能发现的东西。你成为了让我在海量信息中找到“针”的“什么东西”!再次感谢。 - GMc
希望我的问题(以及你的答案)能够帮助未来的其他人! - GMc
@GMc,很高兴能帮助到您 :-) - Tarun Lalwani

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接