Linux:systemd服务之.service文件(二)
systemd通过单元文件(Unit files)来描述和管理不同的系统资源和服务。Systemd 支持的 12 种 Unit 文件类型。其中最常用到的就是Service单元文件。
service文件通常位于以下目录
# 系统或用户自定义的配置文件
/etc/systemd/system/
# 软件运行时生成的配置文件
/run/systemd/system
# 系统或第三方软件安装时添加的配置文件。
/usr/lib/systemd/system
Systemd 默认从目录 /etc/systemd/system/ 读取配置文件。但是,里面存放的大部分文件都是符号链接,指向目录 /usr/lib/systemd/system/,真正的配置文件存放在那个目录。
qing222@qing222-virtual-machine:~$ ls -l /etc/systemd/system
total 160
drwxr-xr-x 2 root root 4096 8月 9 2022 bluetooth.target.wants
drwxr-xr-x 2 root root 4096 8月 9 2022 cloud-final.service.wants
lrwxrwxrwx 1 root root 42 11月 3 2023 dbus-fi.w1.wpa_supplicant1.service -> /lib/systemd/system/wpa_supplicant.service
lrwxrwxrwx 1 root root 37 11月 3 2023 dbus-org.bluez.service -> /lib/systemd/system/bluetooth.service #蓝牙服务
lrwxrwxrwx 1 root root 40 11月 3 2023 dbus-org.freedesktop.Avahi.service -> /lib/systemd/system/avahi-daemon.service
lrwxrwxrwx 1 root root 40 11月 3 2023 dbus-org.freedesktop.ModemManager1.service -> /lib/systemd/system/ModemManager.service
lrwxrwxrwx 1 root root 53 11月 3 2023 dbus-org.freedesktop.nm-dispatcher.service -> /lib/systemd/system/NetworkManager-dispatcher.service
lrwxrwxrwx 1 root root 40 11月 3 2023 dbus-org.freedesktop.oom1.service -> /lib/systemd/system/systemd-oomd.service
lrwxrwxrwx 1 root root 44 11月 3 2023 dbus-org.freedesktop.resolve1.service -> /lib/systemd/system/systemd-resolved.service
一、service文件格式说明
service文件通常由三部分组成:
[Unit]:定义与Unit类型无关的通用选项,用于提供unit的描述信息、unit行为及依赖关系等[Service]:定义如何启动、停止、重启当前服务。[Install]:定义如何安装这个配置文件,即怎样做到开机启动。
以下是一个service文件示例:
[Unit]
Description=My Program Service #Description:服务的简短描述
After=network.target #After:指定该服务需要在 network.target 启动后启动,通常适用于需要网络连接的程序[Service]
ExecStart=/home/qing222/code/test_delete/build-untitled-unknown-Debug/untitled #ExecStart:指定要运行的程序路径
User=root #指定该服务以 root 用户身份运行
Group=root #指定该服务使用 root 组
Restart=always #如果服务崩溃或退出,会自动重启该服务[Install]
WantedBy=multi-user.target #表示该服务将在系统启动进入多用户模式时自动启动
【Unit部分】
Description=
#描述:对服务的一个简短、清晰的描述。
#示例:Description=My Awesome Web ServerDocumentation=
#描述:提供该服务的文档 URL 或手册页。
#示例:Documentation=man:nginx(8) 或 Documentation=https://example.comAfter=
#描述:定义本服务应该在哪些目标或服务之后启动。这只是一个排序依赖,不强制要求所依赖的服务必须启动成功。
#示例:After=network.target syslog.target (确保在网络和日志系统就绪后启动)Before=
#描述:定义本服务应该在哪些目标或服务之前启动。
#示例:Before=graphical.targetRequires=
#描述:定义强依赖关系。如果这里列出的服务启动失败或停止,本服务也会被停止。
#示例:Requires=postgresql.serviceWants=
#描述:定义弱依赖关系。希望所依赖的服务能启动,但即使它启动失败,本服务也会继续启动。这是 推荐的 依赖方式。
#示例:Wants=network.targetConflicts=
#描述:定义冲突关系。如果这里列出的服务正在运行,则本服务不能启动,反之亦然。
#示例:Conflicts=shutdown.targetConditionPathExists:
#描述:只有当指定路径存在时才启动服务
#示例:ConditionPathExists=/opt/application
【Service] 部分】
这是 .service 文件最核心的部分,专门用于定义服务的执行和行为参数。
Type=
#描述:定义进程的启动类型,至关重要。
#可选项:
simple:(默认值)systemd 认为你启动的进程就是主服务进程。如果该进程 fork 子进程后退出,systemd 会认为服务已经结束。
forking:服务进程会在启动后通过 fork() 系统调用创建一个子进程,然后父进程退出。systemd 需要跟踪这个子进程。必须同时设置 PIDFile= 选项,以便 systemd 能识别主进程。
oneshot:类似于 simple,但 systemd 会等待该进程退出后才认为服务启动完成。适用于只执行一次就退出的脚本。
dbus:服务需要在 D-Bus 上获取一个名称,systemd 会在该名称成功获取后才认为服务启动完成。
notify:服务在就绪后会通过 sd_notify() 函数向 systemd 发送一个通知信号。这是最可靠的方式。ExecStart=
#描述:启动服务时执行的命令,必须是绝对路径(可执行文件或脚本的绝对路径)。
#示例:ExecStart=/usr/bin/python3 /opt/myapp/app.py
#注意:命令后面可以跟参数,但不能使用 >, | 等 shell 操作符,除非你通过 /bin/sh -c ‘...’ 来调用。ExecStartPre=, ExecStartPost=
#描述:在 ExecStart= 之前或之后运行的命令。可用于准备工作或清理工作。ExecReload=
#描述:当使用 systemctl reload <service> 时,要执行的命令。通常是让服务重新加载其配置文件。
#示例:ExecReload=/bin/kill -HUP $MAINPIDExecStop=
#描述:当使用 systemctl stop <service> 时,要执行的命令,用于优雅地停止服务。如果未设置,systemd 会直接向所有服务进程发送 SIGTERM 信号。
#示例:ExecStop=/bin/kill -TERM $MAINPIDRestart=
#描述:在什么情况下服务应该自动重启。
#可选项:
no:(默认)不重启。
on-success:仅在服务正常退出(退出码为 0)时重启。
on-failure:仅在服务异常退出(退出码非 0)或被信号杀死时重启。最常用。
always:总是重启,除非被 systemctl stop 停止。
on-abnormal, on-watchdog 等。RestartSec=
#描述:在重启服务之前,systemd 等待多长时间(秒)。
#示例:RestartSec=5User=, Group=
#描述:指定服务以哪个用户和组的身份运行。为了安全,服务不应以 root 身份运行。
#示例:User=nginx Group=nginxWorkingDirectory=
#描述:设置服务进程的工作目录。
#示例:WorkingDirectory=/opt/myapp/Environment=
#描述:设置环境变量。
#示例:Environment=PORT=8080 或 Environment="KEY=VAL" KEY2=VAL2EnvironmentFile:
#描述:从文件中读取环境变量
#示例:EnvironmentFile=/etc/sysconfig/myappStandardOutput=, StandardError=
#描述:将标准输出和标准错误重定向到哪里。
#可选项:journal(到 systemd 日志,默认),syslog,kmsg,file:/path/to/file 等。
【Install部分】
WantedBy:
#定义服务应该在哪个 target 启动时启动,最常用
#例:WantedBy=multi-user.targetRequiredBy:
#定义哪些 target 强依赖本服务
二、调试与故障排除
1、服务不自动启动
●检查是否已启用:systemctl is-enabled my-service
●检查单元文件语法:systemd-analyze verify /etc/systemd/system/my-service.service
●检查依赖是否满足:systemctl list-dependencies --all my-service
2、关机脚本没有执行
●确认 DefaultDependencies=no 设置正确
●确认 RemainAfterExit=yes 设置正确
●确认服务已启动:systemctl start my-shutdown-task
●检查服务状态是否为活动:systemctl is-active my-shutdown-task
3、服务执行超时
●适当调整 TimeoutStartSec 和 TimeoutStopSec 值
●检查脚本是否有死循环或长时间等待
4、权限问题
●检查脚本权限:ls -l /path/to/script.sh
●检查 User/Group 设置是否正确
●使用 su 或 sudo -u 测试用户是否有执行权限
三、基于service服务设置程序开机自启动
详情见我的另一篇博客:Ubuntu设置程序开机自启动:基于.service文件实现
资料参考:
systemd服务管理详解
