systemd.environment-generator 中文手册

译者:金步国


版权声明

本文译者是一位开源理念的坚定支持者,所以本文虽然不是软件,但是遵照开源的精神发布。

其他作品

本文译者十分愿意与他人分享劳动成果,如果你对我的其他翻译作品或者技术文章有兴趣,可以在如下位置查看现有的作品集:

联系方式

由于译者水平有限,因此不能保证译文内容准确无误。如果你发现了译文中的错误(哪怕是错别字也好),请来信指出,任何提高译文质量的建议我都将虚心接纳。


手册索引 . 指令索引systemd-235

名称

systemd.environment-generator — systemd 环境变量生成器

大纲

/path/to/generator

系统生成器目录/run/systemd/system-environment-generators/*
/etc/systemd/system-environment-generators/*
/usr/local/lib/systemd/system-environment-generators/*
/usr/lib/systemd/system-environment-generators/*

用户生成器目录/run/systemd/user-environment-generators/*
/etc/systemd/user-environment-generators/*
/usr/local/lib/systemd/user-environment-generators/*
/usr/lib/systemd/user-environment-generators/*

描述

本文所说的"生成器",本质上是位于上一小节所列目录中的一些可执行程序。 systemd(1) 将会在其自身刚启动的早期、以及重新加载其自身的配置信息时,执行这些环境变量生成器。 注意,环境变量生成器的运行始终早于 systemd.generator(7) 中所描述的其他生成器,并且也早于任何单元的启动。环境变量生成器能够覆盖服务管理器(systemd) 传递给服务单元以及其他进程的环境变量。

生成器的加载目录取决于编译时的配置,一般情况下(--prefix=/usr),就是上一小节所列的目录。 系统环境变量生成器与用户环境变量生成器分别从 system-environment-generators/user-environment-generators/ 目录中加载。 位于列表中较前目录中的生成器,将会覆盖列表中较后目录中的同名生成器,也就是列表中较前的目录的优先级也更高。 因此,可以使用高优先级目录中的一个指向 /dev/null 的同名软连接(或空文件), 去屏蔽低优先级目录中的一个同名生成器(也就是禁止它运行)。 注意,生成器目录的优先级顺序与单元目录的优先级顺序并不相同, 具体就是 /run 目录的优先级比 /etc 目录更高。

在安装或更新了生成器之后,必须执行 systemctl daemon-reload 命令才能最终实际生效。该命令将会重新运行所有生成器来更新环境变量。 在此命令之后启动的所有服务就都使用新的环境变量了。

环境变量生成器的执行与 systemd.generator(7) 中描述的单元生成器的执行类似,不同之处在于:

  • 环境变量生成器按照其文件名的字典顺序依次串行执行。 生成器的输出将会被立即解析,并被立即用于更新环境变量。 因此,后继生成器可以看到先前生成器的成果,并基于它做进一步的修改。

  • 每一个 systemd 实例都会在启动时运行一次环境变量生成器,生成器每一次运行的输出内容可以各不相同。

为了简化对生成器的排序,建议给每个生成器的文件名前面加上两位数字的前缀。

例子

例 1. 一个简单的环境变量生成器,当指定的目录存在时,就扩展特定的环境变量。

# 50-xdg-data-dirs.sh

#!/bin/bash

# 设置默认值
XDG_DATA_DIRS="${XDG_DATA_DIRS:-/usr/local/share/:/usr/share}"

# 若指定的目录存在,则添加进来
if [[ -d /opt/foo/share ]]; then
   XDG_DATA_DIRS=/opt/foo/share:${XDG_DATA_DIRS}
fi

# 显示最终结果
echo XDG_DATA_DIRS=$XDG_DATA_DIRS

例 2. 一个略微复杂的环境变量生成器,读取现存的配置信息,并规范化特定的环境变量。

# 90-rearrange-path.py

#!/usr/bin/env python3

"""

下面是一段 systemd 环境变量生成器的演示代码,用于确保
在可执行文件的目录搜索顺序中, bin 目录之后永远紧跟对应的 sbin 目录。
(例如将 /sbin:/bin:/foo/bar 修改为 /bin:/sbin:/foo/bar )

该示例生成器演示了如何改写先前已经创建的环境变量。
虽然用 bash 很容易实现,但是本例中我们使用
 Python 以表明可以有多种实现方式,同时也便于读者基于此示例,
实现其他更有意思的想法。

"""

import os
import pathlib

def rearrange_bin_sbin(path):
    """确保每一对 …/bin, …/sbin 目录都遵守合理的顺序

    >>> rearrange_bin_sbin('/bin:/sbin:/usr/sbin:/usr/bin')
    '/bin:/sbin:/usr/bin:/usr/sbin'
    """
    items = [pathlib.Path(p) for p in path.split(':')]
    for i in range(len(items)):
        if 'sbin' in items[i].parts:
            ind = items[i].parts.index('sbin')
            bin = pathlib.Path(*items[i].parts[:ind], 'bin', *items[i].parts[ind+1:])
            if bin in items[i+1:]:
                j = i + 1 + items[i+1:].index(bin)
                items[i], items[j] = items[j], items[i]
    return ':'.join(p.as_posix() for p in items)

if __name__ == '__main__':
    path = os.environ['PATH'] # 必须设置此行
                              # 否则将会崩溃
    new = rearrange_bin_sbin(path)
    if new != path:
        print('PATH={}'.format(new))

例 3. 调试环境变量生成器

SYSTEMD_LOG_LEVEL=debug VAR_A=something VAR_B="something else" \
/usr/lib/systemd/system-environment-generators/path-to-generator

参见

systemd-environment-d-generator(8), systemd.generator(7), systemd(1), systemctl(1)