如何在systemd中添加service

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在systemd中添加service相关的知识,希望对你有一定的参考价值。

参考技术A Systemd 服务的内容主要分为三个部分,控制单元(unit)的定义、服务(service)的定义、以及安装部分。

和 SysV init 脚本的差异

过去,*nix 服务(守护精灵)都是用 SysV 启动脚本启动的。SysV 启动脚本就是 Bash 脚本,通常在 /etc/init.d 目录下,可以被一些标准参数如 start,stop,restart 等调用。启动该脚本通常意味着启动一个后台守护精灵(daemon)。shell 脚本常见的缺点就是,慢、可读性不强、太详细又很傲娇。虽然它们很灵活(毕竟那就是代码呀),但是有些事只用脚本做还是显得太困难了,比如安排并列执行、正确监视进程,或者配置详细执行环境。

SysV 启动脚本还有一个硬伤就是,臃肿,重复代码太多。因为上述的“标准参数”必须要靠各个脚本来实现,而且各个脚本之间的实现都差不多(根本就是从一个 skeleton 骨架来的)。而 Systemd 则进行了统一实现,也就是说在 Systemd service 中完全就不需要、也看不到这部分内容。这使得 Systemd 服务非常简明易读,例如 NetworkManager 这一重量级程序的服务,算上注释一共才有 19 行。而它相应的 SysV 启动脚本头 100 行连标准参数都没实现完。

Systemd 兼容 Sysv 启动脚本,这也是为什么这么久我们仍然需要一个 systemd-sysvinit 软件包的原因。但是根据以上理由,最好针对所有您安装的守护精灵都使用原生 Systemd 服务来启动。另外,Systemd 服务可无缝用于所有使用 Systemd 的发行版,意思是 Arch 下编写的脚本拿过来依然能够使用。

通常来说,上游应该在发布源代码的同时发布 Systemd 服务,但如果没发布,你可以对照本教学来为它们写一个并贡献给它们。

关于 SysV init 启动脚本的编写可见openSUSE:Packaging_init_scripts,这主要用于你的服务器,毕竟服务器追求稳定软件更新的不是很勤(但你一定不知道欧盟汽车里的车载系统必须是 Systemd)。

真正开始前需要注意的问题

如上所述,Systemd 的 service 文件是完全跨发行版的,所以有时候没有必要重造轮子。真正编写你的服务前,请确认它在各大发行版中完全就不存在:

我们的 Systemd 服务集合
Fedora Systemd 服务集合
Arch Linux Systemd 服务集合
Gentoo Systemd 服务集合
Debian 中的少量 Systemd 服务
ubuntu 中的少量 Systemd 服务
Systemd 语法

Systemd 语法和 .desktop 文件的语法比较像,也比较类似 Windows 下的 .ini 文件,因此无论对于打包者还是最终用户都是非常容易上手的。

主要格式请见下面的小例子,这里需要说明三点:

Systemd 单元文件中的以 “#” 开头的行后面的内容会被认为是注释
Systemd 下的布尔值,1、yes、on、true 都是开启,0、no、off、false 都是关闭。注:
仅限于 Systemd 文件,比如:

RemainOnExit=yes
并不适用于该文件中嵌入的 shell 语句,比如:

ExecStartPre=/usr/bin/test "x$NETWORKMANAGER" = xyes
这里的 yes 就不能替换。因为等号后面是一条嵌入的 shell 语句。

Systemd 下的时间单位默认是秒,所以要用毫秒(ms)分钟(m)等请显式说明。
一个小例子

NetworkManager 的 Systemd service:

[Unit]
Description=Network Manager
After=syslog.target
Wants=remote-fs.target network.target

[Service]
Type=dbus
BusName=org.freedesktop.NetworkManager
ExecStart=/usr/sbin/NetworkManager --no-daemon
EnvironmentFile=/etc/sysconfig/network/config
ExecStartPre=/usr/bin/test "x$NETWORKMANAGER" = xyes
# Suppress stderr to eliminate duplicated messages in syslog. NM calls openlog()
# with LOG_PERROR when run in foreground. But systemd redirects stderr to
# syslog by default, which results in logging each message twice.
StandardError=null

[Install]
WantedBy=multi-user.target
Also=NetworkManager-wait-online.service

以上是关于如何在systemd中添加service的主要内容,如果未能解决你的问题,请参考以下文章

如何编写systemctl自启动服务 service文件

如何确保在 systemd 中启动服务之前存在延迟?

systemd 和 如何修改和创建一个 systemd service (Understanding and administering systemd)

在特定服务之后启动 systemd 服务? [关闭]

centos中如何把进程以service自启动

centos中如何把进程以service自启动