编写 systemd 服务文件是一个非常重要的技能,特别是当你想要控制系统服务的启动、停止和管理时。systemd 服务文件通常是用于定义如何启动和管理后台服务、进程或命令。掌握如何编写服务文件会让你能够根据需求自定义服务的行为。
systemd 服务文件结构
一个基本的 systemd 服务文件有几个常见的部分,通常分为 [Unit]、[Service] 和 [Install] 三个主要段落。下面将逐一解释每个段落的含义及如何配置。
1. systemd 服务文件基本结构
[Unit]
Description=描述服务的简短信息
After=依赖关系服务,例如 network.target
[Service]
Type=服务类型
ExecStart=启动命令
User=运行服务的用户
Group=运行服务的用户组
Restart=重启策略
Environment=环境变量
[Install]
WantedBy=目标服务(例如 multi-user.target)
[Unit]:定义服务的元数据和依赖关系。[Service]:定义如何启动和管理服务。[Install]:定义服务如何与目标关联,以便在启动时启用或禁用服务。
2. 各个段落的详细解释
[Unit] 段
[Unit] 段主要用来定义服务的描述信息、依赖关系和其他相关设置。
Description: 服务的简短描述,通常是一个简洁明了的服务名称。After: 定义服务启动顺序,表示该服务在某些其他服务或目标启动之后启动。常用的目标包括network.target(网络服务已启动时),multi-user.target(多用户模式下)等。Before: 指定此服务必须在其他服务之前启动。
[Unit]
Description=My Custom Service
After=network.target
[Service] 段
[Service] 段定义了如何启动和管理服务。它是大多数服务文件的核心部分。
Type: 定义服务的类型,常见的类型有:simple:默认类型,ExecStart启动的命令被认为是主进程,systemd会等待它退出。forking:服务进程在启动时会创建子进程(例如后台守护进程),systemd等待该进程的 PID 文件来确定进程是否启动成功。oneshot:执行一次任务后结束,适用于短期任务(例如挂载、卸载等操作)。notify:当主进程通过sd_notify()通知systemd时,systemd会认为服务已经启动。dbus:服务通过 D-Bus 与systemd进行通信。
ExecStart: 定义启动服务时执行的命令或脚本路径。此命令是服务的主进程。ExecStop: 定义停止服务时执行的命令。如果你希望在服务停止时执行额外的命令,可以设置此选项。ExecReload: 当你希望重新加载服务时执行的命令。Restart: 定义服务崩溃时的重启策略。常用的选项包括:no:不自动重启。always:如果服务崩溃或停止,systemd会重启它。on-failure:仅在服务失败时重启。
User和Group: 设置服务运行的用户和用户组。默认是root,但建议为安全考虑使用非root用户来运行应用。Environment: 设置环境变量。
[Service]
Type=simple
ExecStart=/usr/bin/my-service
Restart=on-failure
User=myuser
Group=mygroup
[Install] 段
[Install] 段定义服务如何与启动目标关联,通常是系统启动时自动启动该服务。
WantedBy: 这个选项指定服务在哪个目标(target)下启用。例如,multi-user.target表示服务在多用户模式下启用,graphical.target表示服务在图形界面目标下启用。可以设置多个目标,服务会在达到其中之一时启动。
[Install]
WantedBy=multi-user.target
3. 编写一个简单的 systemd 服务文件
假设我们有一个脚本 /usr/local/bin/my-script.sh,我们想通过 systemd 来管理它。这个脚本会在启动时自动运行。
[Unit]
Description=My Simple Script Service
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/my-script.sh
Restart=on-failure
User=myuser
Group=mygroup
[Install]
WantedBy=multi-user.target
4. 步骤解析
Description=My Simple Script Service:给服务起一个名字,描述它的功能。After=network.target:表示该服务在网络服务启动之后执行。通常网络服务是依赖服务。ExecStart=/usr/local/bin/my-script.sh:指定执行的命令或脚本路径。Restart=on-failure:如果服务崩溃或退出,systemd会自动重启该服务。User=myuser和Group=mygroup:指定服务使用非 root 用户来运行,增加安全性。WantedBy=multi-user.target:表示该服务在multi-user.target阶段启动,通常表示进入多用户模式时自动启动。
5. 配置和启用服务
将上面内容保存为一个 .service 文件,比如 /etc/systemd/system/my-service.service。
启用并启动服务
-
启用服务,使其在系统启动时自动启动:
sudo systemctl enable my-service.service -
启动服务:
sudo systemctl start my-service.service -
查看服务的状态:
sudo systemctl status my-service.service
停止并禁用服务
-
停止服务:
sudo systemctl stop my-service.service -
禁用服务,使其不再在系统启动时自动启动:
sudo systemctl disable my-service.service
6. 日志查看
通过 journalctl 查看服务的日志信息,这对于调试和查看服务的执行情况非常有用。
sudo journalctl -u my-service.service
总结
systemd服务文件由[Unit]、[Service]和[Install]三个主要段落组成。- 在服务文件中,你可以定义服务的描述、启动命令、重启策略、用户等信息。
- 使用
systemctl命令来启用、启动、停止、查看和禁用服务。 WantedBy决定服务在哪个目标(target)下启用,通常用multi-user.target表示服务在多用户模式下启动。
通过这些基本步骤,你可以创建和管理自己的 systemd 服务文件。如果你遇到任何问题,随时可以进一步深入学习 systemd 的更多高级功能。