介绍
越来越多的Linux发行版都采用或计划采用systemd
初始化系统。 这种强大的软件套件可以管理服务器的许多方面,从服务到安装的设备和系统状态。
在systemd
,一个unit
指的是系统知道如何进行操作和管理任何资源。 这是主要的目的是, systemd
工具,知道如何处理。 这些资源使用称为单元文件的配置文件来定义。
在本指南中,我们将向您介绍,不同单位systemd
可以处理。 我们还将介绍一些可以在单元文件中使用的指令,以便确定在系统上处理这些资源的方式。
Systemd单元给你什么?
单位是对象systemd
知道如何管理。 这些基本上是系统资源的标准化表示,可以由守护进程套件管理并由提供的工具操纵。
在某些方面的单位可以说与其他init系统中的服务或作业相似。 但是,一个单元有一个更广泛的定义,因为它们可以用于抽象服务,网络资源,设备,文件系统挂载和隔离的资源池。
在其他init系统中可以用一个统一服务定义处理的想法可以根据它们的焦点被分解成组件单元。 这种功能组织,允许您轻松启用,禁用或扩展功能,而无需修改单元的核心行为。
单位能够轻松实现的一些功能包括:
- 基于套接字的活化 :与服务相关联插座,以便最好细分守护程序本身必须分开处理。 这提供了许多优点,例如延迟服务的开始直到相关联的套接字被首次访问。 这还允许系统在引导过程的早期创建所有套接字,使得可以并行地引导相关联的服务。
- 基于总线的活化 :单位还可以通过提供总线接口上激活
D-Bus
。 当相关总线发布时,可以启动单元。 - 基于路径的激活 :一个单位可以根据上的活动或某些文件系统路径可用性启动。 这利用
inotify
。 - 基于设备的激活 :单位也可以在通过利用相关联的硬件的第一可用性开始
udev
事件。 - 隐含的依赖映射 :大部分依赖关系树为单位的,可通过内置
systemd
本身。 你仍然可以添加依赖和顺序信息,但大多数繁重的提升是为你照顾。 - 实例和模板 :模板单元文件可被用来创建相同的一般单元的多个实例。 这允许所有提供相同的一般功能的微小变化或兄弟单元。
- 方便安全加固 :单位可以通过添加简单的指令,实现了一些相当不错的保密功能。 例如,您可以指定任何或只读访问文件系统的一部分,限制核能力,并指派私人
/tmp
和网络访问。 - 落插件和片段 :单位可以很容易地通过提供片段,将覆盖系统的设备文件的各个部分进行扩展。 这使得在香草和定制单元实现之间切换变得容易。
还有许多其他优点systemd
单元比其他的init系统的工作项目,但是这应该给你,可以使用本机的配置指令被利用的力量的想法。
Systemd单元文件在哪里找到?
定义如何将文件systemd
将处理单元可以在很多不同的位置,其中每一个具有不同的优先级和含义中找到。
该系统的单位文件副本一般都保存在/lib/systemd/system
目录下。 当软件在系统上安装单元文件时,这是默认情况下放置它们的位置。
在此处存储的单元文件能够在会话期间按需启动和停止。 这将是通用的,香草单元文件,常常由上游项目的维护者书面应该部署的任何系统上工作systemd
在其标准实现。 您不应该编辑此目录中的文件。 相反,您应该覆盖该文件,如果需要,使用另一个单位文件位置,将取代该位置的文件。
如果要修改单位的功能,最好的位置,这样做的方式是内/etc/systemd/system
目录下。 在此目录位置中找到的单元文件优先于文件系统上的任何其他位置。 如果您需要修改系统的单位文件副本,在这个目录中放置替换是最安全和最灵活的方法。
如果希望仅覆盖系统单元文件中的特定指令,则实际上可以在子目录中提供单元文件片段。 这些将附加或修改系统副本的指令,允许您仅指定要更改的选项。
要做到这一点,正确的方法是创建一个与单元文件命名的目录.d
附加上结束。 因此,对于一个名为单元example.service
,子目录名为example.service.d
可以创建。 在该目录中与结尾的文件.conf
可用于覆盖或扩展系统的单元文件的属性。
还为在运行时单位定义一个位置/run/systemd/system
。 此目录中发现单元文件有那些之间的优先降落/etc/systemd/system
和/lib/systemd/system
。 此位置中的文件的重量比前一个位置的重量小,但重量比后者大。
该systemd
过程本身使用此位置在运行时创建动态创建单元文件。 此目录可用于在会话期间更改系统的单位行为。 在重新启动服务器时,此目录中所做的所有更改都将丢失。
单位类型
Systemd
根据他们描述的资源类型类别的单位。 确定单元类型的最简单方法是使用其类型Stapling,该Stapling附加到资源名称的末尾。 下面的列表描述的类型提供给单位systemd
:
.service
:服务单位介绍了如何管理服务器上的服务或应用程序。 这将包括如何启动或停止服务,在哪些情况下应该自动启动,以及相关软件的依赖性和订购信息。
-
.socket
:套接字单元文件描述一个网络或IPC插座,或FIFO缓冲器systemd
基于socket激活使用。 这些总是具有相关联的.service
时的活动可以看出,此装置限定了插座上将要启动文件。 -
.device
:描述已被指定为需要的设备的单元systemd
管理由udev
或sysfs
文件系统。 并不是所有的设备都会有.device
文件。 一些情形.device
单位可能是必要的订购,安装,和访问设备。 -
.mount
:本机定义了系统的挂载点由管理systemd
。 这些以安装路径命名,斜线更改为破折号。 内的条目/etc/fstab
可以自动创建单位。 -
.automount
:一个.automount
单元配置一个挂载点,将自动挂载。 这些都必须他们提到,必须有一个匹配的安装点来命名.mount
单元定义安装的细节。 -
.swap
:本单位介绍了系统的交换空间。 这些单元的名称必须反映空间的设备或文件路径。 -
.target
:一个目标单位是用来启动或改变状态时等单位提供同步点。 它们还可以用于使系统进入新的状态。 其他单位指定它们与目标的关系,以便与目标的操作相关联。 -
.path
:该单元定义了可以用于基于路径的激活的路径。 默认情况下,.service
时的路径到达指定状态相同的基本名称的单位将开始。 这里使用inotify
来监视更改的路径。 -
.timer
:一个.timer
单元定义将由管理定时器systemd
,类似cron
为延迟或预定激活作业。 当到达定时器时,将启动匹配单元。 -
.snapshot
:一个.snapshot
单元由自动创建systemctl snapshot
命令。 它允许您在进行更改后重新构建系统的当前状态。 快照不会在会话中存活,并用于回滚临时状态。 -
.slice
:一个.slice
单位与Linux的对照组节点相关联,使资源受到限制或分配给与片段相关联的所有进程。 这个名字反映了其内部等级地位cgroup
树。 默认情况下,单位根据其类型放置在特定切片中。 -
.scope
:适用范围单元被自动创建systemd
从其总线接口接收到的信息。 这些用于管理外部创建的系统进程集。
正如你所看到的,有很多不同的单位systemd
知道如何管理。 许多单元类型一起工作以添加功能。 例如,一些单元用于触发其他单元并提供激活功能。
我们将主要集中在.service
单位,由于其实用性和其管理员需要管理这些单位的一致性。
单位文件的解剖
单元文件的内部结构按节组织。 部分是由一对括号的“表示[
”和“ ]
”与包围的部分名称。 每个部分延伸到后续部分的开始或直到文件的结尾。
单元文件的一般特性
段名称定义明确且区分大小写。 因此,部分[Unit]
将无法正确,如果它的拼写类似的解释[UNIT]
如果您需要添加不规范的部分,以比其他应用程序进行分析systemd
,你可以添加一个X-
前缀部分名称。
在这些部分中,单位行为和元数据通过使用简单的指令来定义,使用键值格式,分配由等号表示,如下所示:
[Section]
Directive1=value
Directive2=value
. . .
在覆盖文件的情况下(如包含在一个unit . type .d
目录),指令可以将它们分配到一个空字符串进行复位。 例如,系统的单位文件副本可能包含设置为如下值的指令:
Directive1=default_value
该default_value
可以在覆盖文件通过引用被淘汰Directive1
没有值,就像这样:
Directive1=
一般情况下, systemd
可以方便,灵活的配置。 例如,多个布尔表达式被接受( 1
, yes
, on
和true
的肯定和0
, no
off
,而且false
的相反的答案)。 可以智能地解析时间,对于无单位值假定为秒,并且组合内部完成的多个格式。
[单位]指令
在大部分单元文件找到的第一个部分是[Unit]
部分。 这通常用于定义单元的元数据并配置单元与其他单元的关系。
虽然部分顺序并不重要,以systemd
解析文件时,这一部分往往放在顶部,因为它提供了单元的概况。 你会在发现一些常见的指令[Unit]
部分如下:
-
Description=
:该指令可以用于描述的名称和单元的基本功能。 它是由不同的返回systemd
工具,所以它是很好的将它设置为短的东西,具体的,内容翔实。 -
Documentation=
:此指令提供的URI的文档列表中的位置。 这些都可以在内部使用man
页或网络访问的URL。 该systemctl status
命令将公开此信息,允许轻松的被发现。 -
Requires=
:这个指令列出在其本单位主要取决于任何单位。 如果激活当前单元,则此处列出的单元也必须成功激活,否则此单元将失败。 默认情况下,这些单位与当前单位并行启动。 -
Wants=
:这个指令是类似Requires=
,但不太严格。Systemd
当本机被激活将尝试启动此处所列的任何单位。 如果找不到这些单元或无法启动,当前单元将继续工作。 这是配置大多数依赖关系的建议方法。 同样,这意味着并行激活,除非被其他指令修改。 -
BindsTo=
:这个指令是类似Requires=
,也导致当前单位停止时,相关单位终止。 -
Before=
:本指令中所列单位将不会启动,直到当前单元标,好像他们是在同一时间激活启动。 这并不意味着依赖关系,如果需要,必须与上述指令之一结合使用。 -
After=
:本指令中所列的单位将启动当前单元之前启动。 这并不意味着依赖关系,如果需要,必须通过上述指令建立。 -
Conflicts=
:这可以用于列出不能在同一时间作为当前单元运行单元。 启动具有此关系的单元将导致其他单元停止。 -
Condition...=
:有许多与起动指令的Condition
,其允许管理员来测试开始之前的单元一定的条件。 这可以用于提供一个通用单元文件,只有在适当的系统上运行。 如果不满足条件,则会正常跳过单元。 -
Assert...=
:类似与启动指令Condition
,这些指令检查运行环境的不同方面来决定的单元是否应该激活。 然而,与Condition
指令,负的结果,使这项指令失败。
使用这些指令和少数其他指令,可以建立有关单元及其与其他单元和操作系统的关系的一般信息。
[Install] Section指令
在单元文件的另一侧,最后一节往往是[Install]
部分。 此部分是可选的,用于定义行为或单位(如果已启用或禁用)。 启用单元会将其标记为在引导时自动启动。 实质上,这是通过将所讨论的单元锁定在另一单元上来实现的,该另一单元在启动时要启动的单元行中的某处。
因此,只有可以启用的单元将具有此部分。 指令中规定当单元启用时应该发生什么:
-
WantedBy=
:本WantedBy=
指令是指定单元应如何使最常用的方法。 该指令允许您指定以类似的方式向依赖关系Wants=
指令确实在[Unit]
部分。 不同之处在于,该指令包括在辅助单元中,允许列出的主单元保持相对干净。 当该指令的单位已启用,目录将在创建/etc/systemd/system
与指定的单位命名的.wants
追加到末尾。 在其中,将创建到当前单元的符号链接,创建依赖关系。 例如,如果当前单元已经WantedBy=multi-user.target
,目录称为multi-user.target.wants
将内创建/etc/systemd/system
(如果尚未提供)和符号链接到当前单元将放置在内。 禁用此单元将删除链接并删除依赖关系。 -
RequiredBy=
:这个指令是非常相似的WantedBy=
指令,而是指定了一个需要的依赖,会导致如果没有达到激活失败。 当启用时,该指令的单位将创建结尾的目录.requires
。 -
Alias=
:此指令允许单位以另一个名字被启用为好。 在其它用途中,这允许功能的多个提供者可用,使得相关单元可以查找公共别名名称的任何提供者。 -
Also=
:这个指令允许单位启用或一组禁用。 此处可以列出在本机活动时始终可用的支持单元。 它们将作为安装任务的组进行管理。 -
DefaultInstance=
:模板单元(后面介绍),它可以产生单位情况不可预知的名字,这可以作为名称的回退值,如果不提供一个合适的名称。
单元特定段指令
在前两个部分之间,您可能会找到特定于单元类型的部分。 大多数单位类型提供仅适用于其特定类型的指令。 这些在根据其类型命名的节中可用。 我们将在这里简要介绍一下。
该device
, target
, snapshot
和scope
单位类型没有单位具体的指示,从而对他们的类型没有关联的部分。
[服务]部分
在[Service]
部分用于提供配置是仅适用于服务。
其中一个应该的内指定基本的东西[Service]
部分是Type=
服务的。 这将按照其进程和守护进程行为对服务进行分类。 因为它告诉了这一点很重要systemd
如何正确管理役,并找出其状态。
该Type=
指令可以是下列之一:
- 简单 :在起始行指定的服务的主要过程。 这是如果默认
Type=
和Busname=
指令都没有设置,但ExecStart=
设置。 任何通信应在单元之外通过适当类型的第二单元进行处理(如通过.socket
如果本机必须使用交流插座)。 - 分叉 :这种服务类型时使用该服务叉一个子进程,几乎立即退出父进程。 这告诉
systemd
该进程仍在运行即使父退出。 - 单稳 :这种类型表明这一进程将是短暂的,而且
systemd
继续与其他单位前,应等待进程退出。 这是默认Type=
和ExecStart=
未设置。 它用于一次性任务。 - DBUS:这表明单位将采取名称D-Bus总线上。 发生这种情况时,
systemd
将继续处理下一个单元。 - 通知 :这表示该服务将发出通知时,它已经完成启动。 该
systemd
进程将等待这继续给其他单位发生之前。 - 空闲 :这表示该服务将不会运行,直到所有的作业调度。
使用某些服务类型时可能需要一些附加指令。 例如:
-
RemainAfterExit=
:此指令通常与所使用的oneshot
类型。 它表示即使在进程退出后,该服务也应被视为活动。 -
PIDFile=
:如果服务类型被标记为“分叉”,该指令用于设置应该包含了应该监视的主要子的进程ID号的文件的路径。 -
BusName=
:此指令应设置到D-Bus总线名称使用“DBUS”的服务类型时,该服务将尝试收购。 -
NotifyAccess=
:指定访问的时候,“通知”的服务类型选择这可能是“无”,“主”,还是应该用于侦听通知插座“所有的默认,”无“,忽略所有状态消息,“main”选项将监听来自主进程的消息,“all”选项将使服务的控制组的所有成员被处理。
到目前为止,我们已经讨论了一些先决条件信息,但我们没有真正定义如何管理我们的服务。 这样做的指令是:
-
ExecStart=
:指定要执行的完整路径和命令的参数来启动进程。 这只能指定一次(“oneshot”服务除外)。 如果命令的路径前面有一个破折号“ - ”字符,则将接受非零退出状态,而不将单元激活标记为失败。 -
ExecStartPre=
:这可以被用于提供主处理开始前应执行的其他命令。 这可以多次使用。 同样,命令必须指定一个完整路径,并且它们前面可以有“ - ”,表示该命令的失败将被允许。 -
ExecStartPost=
:这有完全相同的品质为ExecStartPre=
除了它指定了主进程启动后,将运行命令。 -
ExecReload=
:这个可选指令指示如果有重新加载服务的配置所必需的命令。 -
ExecStop=
:这表示停止服务所需的命令。 如果没有给出,则当服务停止时,进程将立即终止。 -
ExecStopPost=
:这可以用于指定要执行的命令之后停止命令。 -
RestartSec=
:如果自动重新启动该服务已经启用,此规定时间试图重新启动该服务之前等待的时间。 -
Restart=
:这表示在其下的情况下systemd
将尝试自动重新启动该服务。 这可以设置为像“always”,“on-success”,“on-failure”,“on-abnormal”,“on-abort”或“on-watchdog”等值。 这些将根据服务停止的方式触发重新启动。 -
TimeoutSec=
:这个配置的时间量systemd
会等待停止或将其标记为失败或强行杀死它之前停止服务时。 您可以设置不同的超时与TimeoutStartSec=
和TimeoutStopSec=
为好。
[插座]部分
插座单位是很常见的systemd
的配置,因为许多服务实现基于套接字的活化提供更好的并行性和灵活性。 每个插座单元必须具有匹配的服务单元,当该插座接收活动时将被激活。
通过断开服务本身外部的套接字控制,套接字可以提前初始化,并且相关联的服务通常可以并行启动。 默认情况下,套接字名称将尝试在接收到连接时启动同名的服务。 当服务初始化时,套接字将被传递给它,允许它开始处理任何缓冲的请求。
要指定实际的套接字,这些指令是常见的:
-
ListenStream=
:这个定义,支持连续,可靠的通信流套接字的地址。 使用TCP的服务应该使用此套接字类型。 -
ListenDatagram=
:这个定义,它支持快速,可靠的通信数据包数据报套接字的地址。 使用UDP的服务应该设置此套接字类型。 -
ListenSequentialPacket=
:这个定义与最大长度的数据报,保留消息边界连续,可靠的通信地址。 这是最常见的Unix套接字。 -
ListenFIFO
:随着其他的聆听类型,也可以指定一个FIFO缓冲区,而不是一个插座。
听力指令有更多类型,但上面的是最常见的。
插座的其他特性可以通过附加指令控制:
-
Accept=
:此选项确定是否该服务的其他实例会为每个连接启动。 如果设置为false(默认值),一个实例将处理所有连接。 -
SocketUser=
:使用Unix套接字,指定了插座的所有者。 如果未设置,这将是root用户。 -
SocketGroup=
:使用Unix套接字,指定套接字的组所有者。 如果这个或上面没有设置,这将是根组。 如果只SocketUser=
设置,systemd
将设法找到一个匹配的组。 -
SocketMode=
:对于Unix套接字或FIFO缓冲区,这是设置在创建实体的权限。 -
Service=
:如果服务名称不匹配的.socket
名称,该服务可以使用此指令指定。
[装载]部分
安装单位允许挂载点管理从内部systemd
。 安装点以其控制的目录命名,并应用了翻译算法。
例如,删除前导斜杠,将所有其他斜杠转换为短划线“ - ”,并将所有破折号和不可打印字符替换为C风格转义代码。 此转换的结果将用作安装单元名称。 安装单元将对层次结构中其上的其他安装具有隐式依赖性。
安装单位往往直接从翻译/etc/fstab
在引导过程中的文件。 对于自动创建的单元定义和您希望在单元文件中定义的单元定义,以下指令很有用:
-
What=
:对需要被安装在资源的绝对路径。 -
Where=
:安装点,其中资源应安装的绝对路径。 这应该与单元文件名相同,除了使用常规文件系统符号。 -
Type=
:文件系统类型的mount的。 -
Options=
:任何安装了需要应用的选项。 这是一个逗号分隔的列表。 -
SloppyOptions=
:决定如果有一个无法识别的安装选项安装是否会失败的布尔值。 -
DirectoryMode=
:如果父目录需要挂载点创建,这决定了这些目录的权限模式。 -
TimeoutSec=
:配置的时候系统会等到为失败的安装操作标量。
[自动安装]部分
本机允许关联.mount
单元自动安装在开机。 如同.mount
单位,这些单位必须翻译的挂载点的路径来命名。
在[Automount]
部分是非常简单的,与只允许以下两个选项:
-
Where=
:在文件系统的挂载点的绝对路径。 这将匹配文件名,除了它使用常规路径符号而不是翻译。 -
DirectoryMode=
:如果要创建目录需要挂载点或任何父,这将决定这些路径组件的权限设置。
[Swap]部分
交换单位用于配置系统上的交换空间。 这些单元必须使用交换文件或交换设备命名,使用与上述相同的文件系统翻译。
像安装选项,交换单元可以自动创建/etc/fstab
的条目,也可以通过专用单元文件进行配置。
在[Swap]
一个单元部分文件可以包含配置以下指令:
-
What=
:到交换空间的位置的绝对路径,这是否是一个文件或设备。 -
Priority=
:这需要一个整数,指示正在配置的交换的优先级。 -
Options=
:这是在通常设置的任何选项/etc/fstab
的文件可以用此指令,而不是设置。 使用逗号分隔的列表。 -
TimeoutSec=
:的时间量systemd
来标记操作失败前被激活等待调剂。
[路径]部分
路径单元定义一个文件系统路径systmed
可以监控的变化。 必须存在另一个单元,当在路径位置检测到某些活动时,该单元将被激活。 路径活动thorugh确定inotify
事件。
在[Path]
的单位文件的部分可以包含下列指令:
-
PathExists=
:此指令用于检查有问题的路径是否存在。 如果是,则相关单元被激活。 -
PathExistsGlob=
:这是与上述相同,但是支持的文件的glob表达式用于确定路径的存在。 -
PathChanged=
:这个手表的路径更改位置。 如果在观看文件关闭时检测到更改,则激活相关联的单元。 -
PathModified=
:这个手表就像上面指令的变化,但它会激活文件写入以及当文件被关闭的。 -
DirectoryNotEmpty=
:该指令允许systemd
当目录不再是空激活相关单位。 -
Unit=
:指定设备时上面指定的路径条件满足激活。 如果省略,systemd
将寻找一个.service
共享相同的基础单位名称与本机文件。 -
MakeDirectory=
:这确定是否systemd
将观看之前创建的路径有关的目录结构。 -
DirectoryMode=
:如果上述被启用,这将设置必须创建任何路径分量的允许模式。
[定时器]部分
定时器单元用于调度任务在特定时间或一定延迟后操作。 这个单位类型取代或补充一些的功能cron
和at
守护程序。 必须提供一个相关单元,当达到定时器时,该单元将被激活。
在[Timer]
一个单元部分文件可以包含以下一些指令:
-
OnActiveSec=
:此指令允许相关联的单元被相对于所述活化.timer
单元的激活。 -
OnBootSec=
:这个指令时使用相关单位应激活系统启动后指定的时间量。 -
OnStartupSec=
:此指令是类似于上述定时器,而是在相当于systemd
过程本身已启动。 -
OnUnitActiveSec=
:此根据当相关单元上次激活设置一个计时器。 -
OnUnitInactiveSec=
:设置有关计时器时,相关联的单元是最后的标记为非活动状态。 -
OnCalendar=
:这允许您通过指定相对绝对的,而不是一个事件来激活相关单位。 -
AccuracySec=
:该单元用于设定精度与该计时器应粘附到的水平。 默认情况下,相关单元将在到达定时器的一分钟内激活。 该指令的值将决定该窗口中的上限systemd
时间表发生激活。 -
Unit=
:这个指令用于指定应该被激活时,计时器到期的单位。 如果未设置,systemd
将寻找一个.service
单位与本单位相匹配的名称。 -
Persistent=
:如果设置,systemd
会时,如果它会一直在其中计时器是不活跃期间触发计时器激活触发相关单位。 -
WakeSystem=
:设置此指令,可以唤醒系统从挂起如果达到该状态时,计时器。
[切片]部分
的[Slice]
一个单元文件的部分实际上没有任何.slice
单元的具体配置。 相反,它可以包含一些资源管理指令,实际上可用于上面列出的一些单元。
在一些常见的指令[Slice]
段,其也可在其它单元中使用可以在找到systemd.resource-control
手册页。 这些在以下单元特定部分有效:
-
[Slice]
-
[Scope]
-
[Service]
-
[Socket]
-
[Mount]
-
[Swap]
从模板单元文件创建实例单位
我们在本指南中前面提到过模板单元文件用于创建多个单元实例的想法。 在本节中,我们可以更详细地讨论这个概念。
模板单元文件在大多数情况下与常规单元文件没有区别。 然而,这些通过允许文件的某些部分利用在运行时可用的动态信息来提供配置单元的灵活性。
模板和实例单元名称
Template unit files can be identified because they contain an @
symbol after the base unit name and before the unit type suffix. A template unit file name may look like this:
example@.service
When an instance is created from a template, an instance identifier is placed between the @
symbol and the period signifying the start of the unit type. For example, the above template unit file could be used to create an instance unit that looks like this:
example@instance1.service
An instance file is usually created as a symbolic link to the template file, with the link name including the instance identifier. In this way, multiple links with unique identifiers can point back to a single template file. When managing an instance unit, systemd
will look for a file with the exact instance name you specify on the command line to use. If it cannot find one, it will look for an associated template file.
Template Specifiers
The power of template unit files is mainly seen through its ability to dynamically substitute appropriate information within the unit definition according to the operating environment. This is done by setting the directives in the template file as normal, but replacing certain values or parts of values with variable specifiers.
The following are some of the more common specifiers will be replaced when an instance unit is interpreted with the relevant information:
-
%n
: Anywhere where this appears in a template file, the full resulting unit name will be inserted. -
%N
: This is the same as the above, but any escaping, such as those present in file path patterns, will be reversed. -
%p
: This references the unit name prefix. This is the portion of the unit name that comes before the@
symbol. -
%P
: This is the same as above, but with any escaping reversed. -
%i
: This references the instance name, which is the identifier following the@
in the instance unit. This is one of the most commonly used specifiers because it will be guaranteed to be dynamic. The use of this identifier encourages the use of configuration significant identifiers. For example, the port that the service will be run at can be used as the instance identifier and the template can use this specifier to set up the port specification. -
%I
: This specifier is the same as the above, but with any escaping reversed. -
%f
: This will be replaced with the unescaped instance name or the prefix name, prepended with a/
. -
%c
: This will indicate the control group of the unit, with the standard parent hierarchy of/sys/fs/cgroup/ssytemd/
removed. -
%u
: The name of the user configured to run the unit. -
%U
: The same as above, but as a numericUID
instead of name. -
%H
: The host name of the system that is running the unit. -
%%
: This is used to insert a literal percentage sign.
By using the above identifiers in a template file, systemd
will fill in the correct values when interpreting the template to create an instance unit.
结论
When working with systemd
, understanding units and unit files can make administration simple. Unlike many other init systems, you do not have to know a scripting language to interpret the init files used to boot services or the system. The unit files use a fairly simple declarative syntax that allows you to see at a glance the purpose and effects of a unit upon activation.
Breaking functionality such as activation logic into separate units not only allows the internal systemd
processes to optimize parallel initialization, it also keeps the configuration rather simple and allows you to modify and restart some units without tearing down and rebuilding their associated connections. Leveraging these abilities can give you more flexibility and power during administration.