Linux系统服务之一次性服务(2)

本文详细解读了Systemd中的ServiceUnit文件配置,重点介绍了不同类型的服务,如simple、exec、forking、oneshot和dbus,以及它们在启动顺序、依赖管理和执行行为上的差异,特别关注了一次性服务(oneshot)的使用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

接前一篇文章:Linux系统服务之一次性服务(1)

 本文内容参考以下文章:

Systemd OneShot 系统启动时运行一次特定的命令或脚本,并在执行完毕后自动退出-CSDN博客

oneshot一次性服务_type=oneshot-CSDN博客

systemd.service 中文手册 [金步国]

Systemd 入门教程:实战篇 - 阮一峰的网络日志

特此致谢!

三、读懂服务配置文件

上一回已讲过,systemd的Service Unit文件(服务单位文件)用于配置和管理系统中的服务。Service Unit文件的扩展名为.service,通常存储在/etc/systemd/system/目录下或/usr/lib/systemd/system/目录下。

下面是Service Unit文件的一些常见组成部分即配置项:

1. [Unit] 部分

此部分定义服务的基本信息、启动顺序与依赖关系。包括以下字段:

  • Description

描述此服务的简短说明、简单描述。

  • Documentation

给出文档位置。

  • After

指定此服务在哪些其它服务之后启动。

  • Before

指定此服务在哪些其它服务之前启动。

注:After和Before字段只涉及启动顺序,不涉及依赖关系。

  • Requires、Wants、BindsTo

指定此服务所依赖的其它服务。其中:Wants表示当前服务与其所依赖服务之间的弱依赖关系,即如果所依赖服务启动失败或异常退出,并不影响当前服务继续执行;Requies表示当前服务与其所依赖服务之间的强依赖关系,即如果所依赖服务启动失败或异常退出,那么当前服务也必须退出。

注:Requires和Wants字段只涉及依赖关系,不涉及启动顺序。

2. [Service] 部分

此部分定义服务的执行参数和行为,更通俗地说是定义如何启动当前服务。分为命令、类型、重启行为三类。

(1)命令

包括以下字段:

  • ExecStart

在启动该服务时需要执行的命令行(命令+参数)。即指定服务的启动命令或可执行文件路径。

  • ExecStop

当该服务被要求停止时所执行的命令行。即停止该服务时执行的命令。执行完此处设置的所有命令行之后,该服务将被视为已经停止。此字段是可选的。

  • ExecStartPre

在执行ExecStart之前执行的命令行。即启动此服务之前执行的命令。

  • ExecStartPos

在执行ExecStart之后执行的命令行。即启动此服务之后执行的命令。

  • ExecStopPost

在该服务停止之后所执行的命令行。无论服务是否启动成功, 此选项中设置的命令都会在服务停止后被无条件的执行。此字段是可选的。

  • ExecReload

当该服务被要求重新载入配置时所执行的命令行。即重新加载服务配置时执行的命令。此字段是可选的。

  • Environment

设置环境变量。

  • EnvironmentFile

从指定的文件中加载环境变量。即指定当前服务的环境参数文件。

(2)类型

Type字段用于定义服务的类型,其指定了如何启动和管理服务的主进程。通过在Service Unit文件中设置Type选项,可以根据服务的特性和需求选择合适的服务类型,以确保systemd正确地管理和监控服务的状态和行为。Type选项的值可以是以下之一:

  • simple(默认值)

如果设为simple(当设置了ExecStart=、 但是没有设置Type=BusName=时,这是默认值), 那么ExecStart=进程就是该服务的主进程,并且systemd会认为在创建了该服务的主服务进程之后,该服务就已经启动完成。

如果此进程需要为系统中的其它进程提供服务,那么必须在该服务启动之前先建立好通信渠道(例如套接字)。 这样,在创建主服务进程之后、执行主服务进程之前,即可启动后继单元,从而加快了后继单元的启动速度。

simple最常见的服务类型。当使用simple类型时,systemd假定服务的主进程会一直运行,直到服务被显式停止或发生错误。这是大多数服务的默认类型。

  • exec

execsimple类似,不同之处在于,只有在该服务的主服务进程执行完成之后,systemd才会认为该服务启动完成。其它后继单元必须一直阻塞到这个时间点之后才能继续启动。换句话说,simple表示当fork()返回时,即算是启动完成,而exec则表示仅在fork()execve()函数都执行成功时,才算是启动完成。这就意味着对于exec类型的服务来说,如果不能成功调用主服务进程(例如User=不存在、或者二进制可执行文件不存在),那么systemctl start将会执行失败。

  • forking

如果设为forking,那么表示ExecStart=进程将会在启动过程中使用fork()系统调用。也就是当所有通信渠道都已建好、启动亦已成功之后,父进程将会退出,而子进程将作为主服务进程继续运行。 这是传统UNIX守护进程的经典做法。 在这种情况下,systemd 会认为在父进程退出之后,该服务就已经启动完成。

如果使用了此种类型,那么建议同时设置PIDFile=选项,以帮助systemd准确可靠的定位该服务的主进程。systemd将会在父进程退出之后 立即开始启动后继单元。

forking适用于那些在启动过程中会创建一个子进程的服务。在这种类型的服务中,systemd会等待主进程启动,并通过监视子进程的退出来确定服务的启动状态。通常,服务的主进程会立即启动子进程,然后退出,而子进程则负责实际的服务运行。

  • oneshot

oneshotsimple类似,不同之处在于,只有在该服务的主服务进程退出之后,systemd才会认为该服务启动完成,才会开始启动后继单元。此种类型的服务通常需要设置RemainAfterExit=选项。 当Type=ExecStart=都没有设置时,Type=oneshot就是默认值。

oneshot适用于只需执行一次操作的服务,例如在系统启动时运行一个脚本或执行一个命令。当服务的主进程退出后,systemd将认为服务已经完成,并将其标记为已停止。

  • dbus

dbussimple类似,不同之处在于,该服务只有获得了BusName=指定的D-Bus名称之后,systemd才会认为该服务启动完成,才会开始启动后继单元。设为此类型相当于隐含的依赖于dbus.socket单元。当设置了BusName=时, 此类型就是默认值。

用于通过DBus系统总线启动的服务。这种类型的服务通常用于与其它进程进行通信或提供DBus接口。

  • notify

notifyexec类似,不同之处在于,该服务将会在启动完成之后通过sd_notify(3)之类的接口发送一个通知消息。systemd将会在启动后继单元之前,首先确保该进程已经成功的发送了这个消息。

如果设为此类型,那么下文的NotifyAccess=将只能设为非none值;如果未设置NotifyAccess=选项、或者已经被明确设为none,那么将会被自动强制修改为main

notify适用于在服务启动完成后向systemd发送通知的服务。服务主进程应在启动完成后向systemd发送一个特定的信号,以通知systemd该服务已准备好接受请求。

注意:目前Type=notify尚不能与PrivateNetwork=yes一起使用。

  • idle

idlesimple类似,不同之处在于,服务进程将会被延迟到所有活动任务都完成之后再执行。这样可以避免控制台上的状态信息与shell脚本的输出混杂在一起。

idle适用于以非常低优先级运行的服务。这种类型的服务将在所有其它活动任务完成后才会启动。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝天居士

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值