Systemd 学习总结
儿时练功易,老来学艺难。
导航
0、前言
当我们打开 Linux 主机以命令行模式或图形化模式进入系统之后,系统就已经为我们提供了很多的服务,如:打印服务、计划任务服务、邮件服务等等,那么这些服务是如何被启动起来的呢?在此之前我们先了解一下 Linux 主机的启动过程:

- 点击主机开机按钮,CPU 开始加载固件程序(即 BIOS 上电自检),待加载完毕之后 BIOS 便获得了 CPU 的控制权,然后 BIOS 会去加载开机启动顺序中指定的系统入口点(安装系统的光驱、硬盘的入口点)。
- 待 BIOS 加载了入口点处的引导装载程序 (GRUB2)之后,CPU 控制权此时便到了 GRUB2 的手里,GRUB2 接着开始加载硬盘中安装的 Linux 内核。
- 待 Linux 内核初始化完成之后,CPU 的控制权此时便到了 Linux 内核手中,往后 CPU 的控制权便一直掌握在 Linux 内核手中。
- 但 Linux 内核对于用户来说并不可直接被使用、而且也并未提供什么功能,于是它又雇佣了一个管家(init、systemd)并授予了一些权利,来代替它去做一些系统管理的事情。而这个管家便是 Linux 内核掌权之后启动的第一个外部程序,也是未来所有其它进程之父。
早期 各 Linux 发行商为自家 Linux 内核配备的管家是 init 这个程序,该管家的特点是:(1)基于脚本式的方式去管理服务,服务的启动/停止/状态查看都是通过 /etc/init.d/ 下的 bash 脚本来实现的。(2)开机启动各种服务的时候,只能一个一个依序进行,不能够并行启动。(3)服务之间的依赖问题需要管理员手动处理。(4)系统环境切换依赖于 /etc/rc*.d/ 中的脚本。
如今 各 Linux 发行商为自家 Linux 内核配备的管家基本都是 systemd 这个程序,该管家的特点是:(1)基于配置文件(服务单位 Unit )的方式去管理服务,服务的管理更灵活、更简单。(2)支持并行启动开机自启应用。(3)服务之间的依赖会自动检查,并自动唤醒。(4)兼容旧有的 init 服务脚本启动方式。
由于如今的 Linux 使用的服务管理方式多是 Systemd,因此学会它还是很有必要的。
注:Linxu 内核启动的第一个程序是 systemd,而 systemd 启动的第一个服务单元是 default.target,它一般被命令
systemctl set-default multi-user.target链接到了 multi-user.target 或 graphical.target。当 systemd 启动任何服务单元 Unit 文件的时候,systemd 首先去启动参数 Requires 和目录
/etc/systemd/system/a.target.requires/关联的服务,然后再开始启动参数 Wants 和目录/etc/systemd/system/a.target.want/关联的服务。systemd 找寻 default.target 单元文件时的目录查找顺序: /etc/systemd/system/default.target ↓ /run/systemd/system/default.target ↓ /usr/local/lib/systemd/system/default.target ↓ /usr/lib/systemd/system/default.target ↓ /lib/systemd/system/default.target
1、工具介绍
Systemd 是基于服务单位 Unit 来管理守护进程和系统资源的,它将这些服务单位 Unit 划分成了 service、target、timer、path、socket 等 12 种不同的类型,每种类型分别对应着不同的功能和应用场景以方便管理员使用。此外,Systemd 还维护着一个名为 journald 的日志系统来记录它所管理的服务在运行时产生的各种日志信息。

如图所见,Systemd 在 Linux 系统中的地位很重要,因为它必须确保系统启动并准备就绪,所以它承担的事情也比较多,例如:
- 它会启动所有你需要的后台服务,例如网络、打印、容器、数据库等。【后台服务管理】
- 它会自动挂载所有不同的文件系统和磁盘,以便可以随时访问。【开机挂载】
- 一旦进入图形提示符,它就会处理用户登录、息屏和关机。【用户登录与会话管理】
- 它会自动清理临时垃圾文件,或者每天自动备份数据。【定时任务】
- 它会实时收集并归档内核、系统服务以及各种软件打印出来的日志。【日志记录】
2、配置结构
Systemd 管理的服务所对应的服务单元 Unit 文件的存放路径如下(注:这些路径存在 优先级覆盖关系):
| 目录路径 | 作用与特点 | 适用场景 |
|---|---|---|
/etc/systemd/system/ |
最高优先级。存放管理员手动创建或修改的单元文件,以及开机自启服务的软链接。 | 用户自定义服务、修改系统默认配置。 |
/run/systemd/system/ |
中等优先级。存放系统运行期间动态生成的临时单元文件(重启后丢弃)。 | 程序运行时临时产生的服务、挂载点。 |
/lib/systemd/system/ (或 /usr/lib/systemd/system/) |
最低优先级。存放通过软件包管理器(如 apt、dnf)安装的服务默认配置。 |
系统与软件自带的原始配置,请勿直接修改。 |
此外,在修改单元配置文件时,官方建议不要直接在源文件(即 /usr/lib/systemd/system/* 中的单元文件)中进行修改,而是优先在 /etc/systemd/system/* 中进行修改。例如,如果你想额外修改 vsftpd.service 的话,则应该按如下方式处理:
| 目录路径 | 作用说明 |
|---|---|
/usr/lib/systemd/system/vsftpd.service |
官方释出的预设设定档,不要动。 |
/etc/systemd/system/vsftpd.service.d/custom.conf |
在 /etc/systemd/system 底下建立与设定档相同档名的目录,但是要加上 .d 的副档名。然后在该目录下建立设定档即可。另外,设定档最好附档名取名为 .conf 较佳! 在这个目录下的档案会“累加其他设定”进入 /usr/lib/systemd/system/vsftpd.service 内。 |
/etc/systemd/system/vsftpd.service.wants/* |
此目录内的档案为连结档,设定相依服务的连结。意思是启动了 vsftpd.service 之后,最好再加上这目录底下建议的服务。 |
/etc/systemd/system/vsftpd.service.requires/* |
此目录内的档案为连结档,设定相依服务的连结。意思是在启动 vsftpd.service 之前,需要事先启动哪些服务的意思。 |
最终,当执行 systemctl start vsftpd.service 命令时,systemctl 会将以上 4 个目录文件中的配置信息都聚合起来形成一份运行时 service 服务单元去执行。不过这种用法个人觉得还是太麻烦,还不如直接拷贝一份源文件在 /etc/systemd/system/vsftpd.service 然后直接修改它来的容易。
3、Unit 实例
Systemd 所划分的 12 种 Unit 类型如下:
| Unit 类型 | 文件后缀 | 作用 | 常见用途 |
|---|---|---|---|
| Service Unit | .service |
管理系统服务/进程 | 启动 nginx、docker、ssh |
| Target Unit | .target |
管理一组 Unit 的集合 | 类似运行级别 |
| Timer Unit | .timer |
定时任务 | 替代 cron |
| Path Unit | .path |
监控文件路径变化 | 文件变化触发任务 |
| Slice Unit | .slice |
管理资源分组 | CPU/内存限制 |
| Mount Unit | .mount |
管理文件系统挂载 | 自动挂载磁盘 |
| Automount Unit | .automount |
按需挂载文件系统 | 延迟挂载 |
| Swap Unit | .swap |
管理 swap 分区/文件 | 开启交换空间 |
| Scope Unit | .scope |
管理外部进程 | 用户会话、容器 |
| Socket Unit | .socket |
管理 socket 通信 | socket 激活服务 |
| Device Unit | .device |
管理硬件设备 | 磁盘、USB 设备 |
| Snapshot Unit | .snapshot |
保存当前状态 | 系统状态快照 |
3.0、通用块
每种 Unit 配置文件的语法格式基本都是由 3 大块组成:通用的【Unit 块 + Install 块】,以及独属于每种 Unit 类型专属的【Service 块、Timer 块、Path 块等】。下面我将展示 通用块【Unit 块 + Install 块】的常用参数,而关于每种 Unit 专属块 的常用参数则在各自的小节进行展示。
3.0.1、Unit 块参数
【Unit 块】常用参数列表:
| 设定参数 | 参数意义说明 |
|---|---|
Description |
对当前 Unit 的功能进行简短描述,执行 systemctl status 时通常可以看到。 |
Documentation |
指定该 Unit 的相关文档地址,可以是 man:、info: 或 URL。 |
Requires |
强依赖关系。当前 Unit 启动时,会尝试启动这里指定的 Unit;如果依赖 Unit 被停止或启动失败,当前 Unit 通常也会受到影响。 |
Wants |
弱依赖关系。当前 Unit 启动时,会尝试启动这里指定的 Unit;但依赖 Unit 启动失败,一般不会导致当前 Unit 失败。 |
Requisite |
要求指定 Unit 已经处于 active 状态,否则当前 Unit 不会启动;它本身不会主动启动依赖 Unit。 |
BindsTo |
比 Requires 更强的绑定关系。依赖 Unit 消失或变为 inactive 时,当前 Unit 也会停止。 |
PartOf |
建立停止/重启传播关系。当指定 Unit 被停止或重启时,当前 Unit 也会执行相应操作。 |
Conflicts |
表示两个 Unit 不能同时运行。启动一个 Unit 时,会停止与它存在 Conflicts 关系的 Unit。 |
Before |
指定当前 Unit 必须在某些 Unit 之前启动。只负责启动顺序,不建立依赖关系。 |
After |
指定当前 Unit 必须在某些 Unit 之后启动。只负责启动顺序,不建立依赖关系。 |
Before / After |
可以同时使用。例如 After=network.target 表示当前 Unit 的启动顺序排在 network.target 后面。 |
Condition... |
启动前进行条件检查。条件不满足时,Unit 会被跳过,而不是认为启动失败。 |
Assert... |
启动前进行断言检查。条件不满足时,Unit 启动会被认为失败。 |
DefaultDependencies |
是否自动添加 systemd 默认依赖关系,默认通常为 yes。 |
OnFailure |
当前 Unit 启动失败时,自动激活指定的 Unit。 |
OnSuccess |
当前 Unit 成功停止/完成后,自动激活指定的 Unit。 |
JobTimeoutSec |
设置等待该 Unit Job 完成的超时时间。 |
StartLimitIntervalSec |
在指定时间窗口内限制 Unit 的启动次数。 |
StartLimitBurst |
指定时间窗口内允许的最大启动次数,通常与 StartLimitIntervalSec 配合使用。 |
3.0.2、Install 块参数
【Install 块】常用参数列表:
| 设定参数 | 参数意义说明 |
|---|---|
WantedBy |
指定当前 Unit 应该被哪个 Target 以 Wants 关系拉起。执行 systemctl enable 时,会在对应 Target 的 .wants/ 目录中创建符号链接。 |
RequiredBy |
与 WantedBy 类似,但建立的是 Requires 关系,启用当前 Unit 时会在对应 Target 的 .requires/ 目录建立链接。 |
Also |
当执行 systemctl enable 或 disable 当前 Unit 时,同时对指定的其他 Unit 执行相应操作。 |
Alias |
为当前 Unit 创建别名。启用 Unit 时,会建立对应的符号链接,使得可以通过别名操作同一个 Unit。 |
3.1、Service
单元介绍:最基本的单元,主要用来启动服务进程,同时也是 target、timer、path、socket 这些单元所需的基本单元。
期望目标:一条命令启动/停止 nginx 服务进程。
# cat nginx.service
[Unit]
Description=Nginx Web Server
After=network.target
[Service]
ExecStart=/usr/sbin/nginx
ExecStop=/usr/sbin/nginx -s stop
Restart=always
[Install]
WantedBy=multi-user.target
【Service 块】常用参数列表:
| 设定参数 | 参数意义说明 |
|---|---|
Type |
指定服务的启动类型,常见有 simple、exec、forking、oneshot、dbus、notify、idle。 |
ExecStart |
指定启动服务时执行的命令,是最核心的 Service 参数之一。 |
ExecStartPre |
在 ExecStart 之前执行的命令,常用于启动前检查或准备工作。 |
ExecStartPost |
ExecStart 成功后执行的命令。 |
ExecReload |
执行 systemctl reload xxx 时运行的命令,用于让程序重新加载配置。 |
ExecStop |
执行 systemctl stop xxx 时运行的命令。 |
ExecStopPost |
服务停止后执行的命令,常用于清理工作。 |
Restart |
指定服务退出后是否自动重新启动,例如 no、on-success、on-failure、always。 |
RestartSec |
服务自动重启前等待多长时间。 |
RestartPreventExitStatus |
指定某些退出状态码时禁止自动重启。 |
RestartForceExitStatus |
指定某些退出状态码时强制触发自动重启。 |
User |
指定服务进程以哪个用户身份运行。 |
Group |
指定服务进程使用的用户组。 |
WorkingDirectory |
指定服务进程的工作目录。 |
Environment |
设置服务运行时的环境变量。 |
EnvironmentFile |
从指定文件读取环境变量。 |
ExecSearchPath |
指定执行程序时搜索可执行文件的路径。 |
PIDFile |
指定服务 PID 文件的位置,常用于 Type=forking 的服务。 |
RemainAfterExit |
对 Type=oneshot 等服务有用,表示命令执行结束后 Unit 是否继续保持 active 状态。 |
TimeoutStartSec |
设置服务启动超时时间。 |
TimeoutStopSec |
设置服务停止超时时间。 |
TimeoutAbortSec |
服务被中止时允许等待的时间。 |
KillMode |
指定停止服务时 systemd 如何处理服务进程,例如 control-group、process、mixed。 |
KillSignal |
指定停止服务时首先发送的信号,默认通常为 SIGTERM。 |
SuccessExitStatus |
指定哪些退出状态被认为是正常退出。 |
StandardOutput |
指定标准输出的去向,例如 journal、null、file: 等。 |
StandardError |
指定标准错误输出的去向。 |
SyslogIdentifier |
设置写入 journal 时使用的标识名称。 |
Nice |
设置进程的 CPU 调度优先级。 |
OOMScoreAdjust |
调整进程被 Linux OOM Killer 杀死时的优先级。 |
LimitNOFILE |
限制进程能够打开的最大文件描述符数量。 |
LimitNPROC |
限制进程能够创建的进程/线程数量。 |
PrivateTmp |
为服务提供独立的 /tmp 和 /var/tmp 环境。 |
ProtectSystem |
限制服务对系统目录的写权限,提高安全性。 |
ProtectHome |
限制服务访问 /home、/root、/run/user 等目录。 |
NoNewPrivileges |
禁止服务进程通过 execve() 获取新的特权,提高安全性。 |
由于 Type 是 [Service] 中非常重要的参数,因此下面将对该参数进行详细说明:
| Type | 含义 |
|---|---|
simple |
ExecStart 启动的进程就是主进程,systemd 启动命令后通常就认为服务已经启动。 |
exec |
类似 simple,但会等待程序真正成功执行后再认为启动成功。 |
forking |
程序启动后会 fork 到后台,传统守护进程常使用这种方式。 |
oneshot |
执行一次命令后退出,常用于脚本、初始化任务。 |
notify |
程序通过 systemd 的通知机制主动告诉 systemd “我已经启动完成”。 |
dbus |
程序成功获得指定 D-Bus 名称后认为启动完成。 |
idle |
等待其他任务完成后再启动,主要用于调整启动时机。 |
3.2、Target
单元介绍:搭配 service 或其他类型的 Unit 使用,可以理解为是 一组 Unit 的集合,它本身通常不执行程序,而是用来组织和控制多个 service、mount、socket 等 Unit 的启动顺序。
期望目标:通过一条命令便可同时启动这些 web 业务服务:nginx、mysql、redis。
# cat nginx.service mysql.service redis.service
...省略...
# cat myapp.target
[Unit]
Description=My Application Stack
Requires=nginx.service mysql.service redis.service
After=nginx.service mysql.service redis.service
【Target 块】常用参数列表:
注:该 Unit 的配置文件无专属块参数,只需要通用的 Unit、Install 块即可。
3.3、Timer
单元介绍:搭配 service 使用,可以理解为是 service 的专属定时器,时间单位可精细到秒。【注:cron 的最小时间单位是分钟】
期望目标:定时执行服务程序。
# cat backup.service
[Unit]
Description=backup file
[Service]
Type=oneshot
ExecStart=/usr/local/bin/file-backup.sh
# cat backup.timer
[Unit]
Description=backup my server timer
[Timer]
OnBootSec=2hrs # 开机后 2 小时开始执行一次这个 backup.service。
OnUnitActiveSec=2days # 自从第一次执行后,未来每两天要执行一次 backup.service。
[Install]
WantedBy=multi-user.target
注:持续计时参数。
# 每天凌晨执行备份。 [Timer] OnCalendar=*-*-* 02:00:00 Persistent=true
【Timer 块】常用参数列表:
| 设定参数 | 参数意义说明 |
|---|---|
OnBootSec |
系统启动后经过指定时间后触发 Timer,例如 OnBootSec=5min 表示系统启动 5 分钟后执行。 |
OnStartupSec |
systemd 用户实例或系统实例启动后经过指定时间触发。系统级 Timer 中通常与 OnBootSec 类似。 |
OnUnitActiveSec |
被触发的 Unit 上一次被激活后,经过指定时间再次触发。例如 OnUnitActiveSec=1h 表示服务激活后每隔 1 小时再次触发。 |
OnUnitInactiveSec |
被触发的 Unit 变为 inactive 后,经过指定时间再次触发。 |
OnCalendar |
按日历时间触发,例如 OnCalendar=daily、OnCalendar=*-*-* 02:00:00。 |
OnActiveSec |
Timer 本身被激活后经过指定时间触发。 |
OnFailureSec |
Timer 所关联的 Unit 失败后经过指定时间触发。 |
Persistent |
是否补执行错过的任务。设置为 true 后,如果机器关机期间错过了定时任务,下一次启动时会补执行。 |
AccuracySec |
Timer 触发时间允许的误差范围,用于让 systemd 合并多个定时任务以减少系统唤醒。 |
RandomizedDelaySec |
在计划触发时间基础上增加随机延迟,可避免大量机器同时执行任务。 |
Unit |
指定 Timer 触发哪个 Unit。默认情况下,xxx.timer 通常触发同名的 xxx.service。 |
3.4、Path
单元介绍:搭配 service 使用,当某个文件的内容/状态出现变动时,触发对绑定 service 的启动。
期望目标:当文件 /tmp/test.txt 被修改(echo hello >> /tmp/test.txt)时,系统会自动执行 file-change.sh 脚本。
# cat file-change.service
[Unit]
Description=Handle file change
[Service]
Type=oneshot
ExecStart=/usr/local/bin/file-change.sh
# cat file-change.path
[Unit]
Description=Monitor test file
[Path]
PathModified=/tmp/test.txt
[Install]
WantedBy=multi-user.target
【Path 块】常用参数列表:
| 设定参数 | 参数意义说明 |
|---|---|
PathExists |
指定路径存在时触发关联的 Service。 |
PathExistsGlob |
使用通配符匹配路径,只要匹配的路径存在就触发 Service。 |
PathChanged |
指定文件或目录发生变化时触发 Service。 |
PathModified |
指定文件被修改时触发 Service。相比 PathChanged,更关注文件内容修改。 |
DirectoryNotEmpty |
指定目录不为空时触发 Service,常用于监控“文件投递目录”。 |
Unit |
指定 Path Unit 触发哪个 Unit。默认情况下,xxx.path 通常触发同名的 xxx.service。 |
MakeDirectory |
创建监控路径不存在的父目录。 |
3.5、Slice
单元介绍:搭配 service 使用,让加入到同一个资源组的服务共用同一个环境的资源,可以起到限制进程无限使用系统资源的作用。
期望目标:让 nginx 服务所能使用的最大 CPU 不超过 40%,最大内存不超过 2G。
# cat nginx.service
[Unit]
Description=Nginx Web Server
After=network.target
[Service]
ExecStart=/usr/sbin/nginx
ExecStop=/usr/sbin/nginx -s stop
Restart=always
Slice=web.slice
[Install]
WantedBy=multi-user.target
# cat web.slice
[Slice]
CPUQuota=40%
MemoryMax=2G
【Slice 块】常用参数列表:
| 设定参数 | 参数意义说明 |
|---|---|
CPUQuota |
限制该 Slice 最多使用多少 CPU,例如 CPUQuota=50% 表示最多使用 50% 的一个 CPU 核心。 |
MemoryMax |
设置该 Slice 可使用的最大内存,超过限制后可能触发 OOM 处理。 |
MemoryHigh |
设置内存使用的“高水位”,超过后 systemd 会对该 Slice 施加内存压力控制,但通常不会像 MemoryMax 那样直接作为硬限制。 |
MemoryMin |
设置该 Slice 应获得的最低内存保障。 |
MemoryLow |
设置内存保护的低水位。 |
TasksMax |
限制该 Slice 中最多允许创建多少个进程/线程。 |
IOWeight |
设置磁盘 I/O 权重,用于不同 Slice 之间的 I/O 资源竞争。 |
IODeviceWeight |
针对特定设备设置 I/O 权重。 |
BlockIOAccounting |
是否统计该 Slice 的块设备 I/O 使用情况。 |
CPUAccounting |
是否统计 CPU 使用情况。 |
MemoryAccounting |
是否统计内存使用情况。 |
TasksAccounting |
是否统计任务数量。 |
3.6、Mount
单元介绍:该 Unit 相当于是对系统 fatab/mount 的另一种实现,同时也是 Automount 自动挂载单元的基本 Unit。
期望目标:通过 systemctl start data.mount 将 sdb1 这个分区挂载到 /data 目录下。
# cat data.mount
[Unit]
Description=Mount data disk
[Mount]
What=/dev/sdb1
Where=/data
Type=ext4
Options=defaults
[Install]
WantedBy=multi-user.target
【Mount 块】常用参数列表:
| 设定参数 | 参数意义说明 |
|---|---|
What |
指定要挂载的设备、磁盘分区、LVM、NFS 等来源,例如 /dev/sdb1。 |
Where |
指定挂载点,例如 /data。这是 Mount Unit 最核心的参数之一。 |
Type |
指定文件系统类型,例如 ext4、xfs、nfs 等。 |
Options |
指定挂载参数,相当于 mount -o 后面的参数,例如 defaults,noatime。 |
SloppyOptions |
是否允许部分无法识别的挂载选项被忽略。 |
LazyUnmount |
Unit 停止时是否使用 lazy unmount。 |
ForceUnmount |
Unit 停止时是否强制卸载。 |
DirectoryMode |
如果挂载点目录不存在,指定创建目录时使用的权限。 |
TimeoutSec |
设置挂载操作的超时时间。 |
3.7、Automount
单元介绍:搭配 mount 单元使用,当指定的目录被读取时,自动触发对绑定 mount 的启动。
期望目标:正常情况下,backup.mount 这个分区并不会被挂载,但是当执行 ls /backup 的时候,这个分区才会被挂载。
# cat backup.mount
[Unit]
Description=NFS Backup Mount
[Mount]
What=192.168.1.10:/backup
Where=/backup
Type=nfs
Options=defaults
# 注意,这里没有配置 WantedBy= 选项,因为它不需要通过开机启动。
# cat backup.automount
[Unit]
Description=Automount backup directory
[Automount]
Where=/backup
TimeoutIdleSec=300
[Install]
WantedBy=multi-user.target
注:mount 一般用于开机自启,而 automount 则用于按需自启。
【Automount 块】常用参数列表:
| 设定参数 | 参数意义说明 |
|---|---|
Where |
指定自动挂载点,例如 /data。 |
DirectoryMode |
如果挂载点目录不存在,指定创建目录时的权限。 |
TimeoutIdleSec |
指定挂载点空闲多长时间后自动卸载。例如 TimeoutIdleSec=10min。 |
4、命令管理
4.1、systemctl 命令用法
systemd 用来管理服务的命令只有一条,即 systemctl,以下便是关于该命令最常见的用法:
# -------------------- 1. 服务管理 --------------------
# 启动/停止/重启/重载/查看服务
systemctl start/stop/restart/reload/status nginx
# 设置/取消/开机自启,以及禁止/取消禁止服务被自启
systemctl enable/disable/mask/unmask nginx
# 判断服务 是否自启/是否正在运行/是否启动失败
systemctl is-enabled/is-active/is-failed nginx
# -------------------- 2. 服务状态查看 --------------------
# 查看系统中所有已安装的 Unit 文件的预设状态
systemctl list-unit-files
# 查看所有 Unit 的运行状态,包括 inactive
systemctl list-units --all
# 按 Unit 类型查看当前启动的 Unit
systemctl list-units --type=service
systemctl list-units --type=socket
systemctl list-units --type=timer
systemctl list-units --type=mount
systemctl list-units --type=target
# 查看启动失败的 Unit
systemctl list-units --state=failed # 等价于 systemctl --failed
# 查看所有 Socket 服务的状态,不论是否启动
systemctl list-sockets
# 查看所有 Timer 服务的状态,不论是否启动
systemctl list-timers
# 查看所有 Path 服务的状态,不论是否启动
systemctl list-paths
# 查看所有 Automount 服务的状态,不论是否启动
systemctl list-automounts
# -------------------- 3. Unit 文件管理 --------------------
# 查看 Unit 的属性信息
systemctl show nginx
# 查看 Unit 文件内容
systemctl cat nginx
# 编辑 Unit 文件(修改内容会被添加到 /etc/systemd/system/nginx.service.d/override.conf 文件中)
systemctl edit nginx
# 编辑完整 Unit 文件(可直接在原来的基础上进行修改)
systemctl edit --full nginx
# 修改 Unit 文件后重新加载 systemd
systemctl daemon-reload
# -------------------- 4. Unit 依赖查询 --------------------
# 查看 Unit 的依赖关系
systemctl list-dependencies nginx
# 查看反向依赖
systemctl list-dependencies --reverse nginx
# -------------------- 5. Target 管理 --------------------
# 查看默认 Target
systemctl get-default
# 设置默认 Target
systemctl set-default multi-user.target
# 切换到指定 Target
systemctl isolate multi-user.target
# 查看 Target 的依赖
systemctl list-dependencies multi-user.target
# -------------------- 6. 系统操作 --------------------
# 重启系统
systemctl reboot
# 关机
systemctl poweroff
# 挂起
systemctl suspend
# 休眠
systemctl hibernate
# 进入救援模式
systemctl rescue
# 进入紧急模式
systemctl emergency
4.2、journalctl 命令用法
前面我们说过,systemd 不仅可以用来管理服务,同时它还提供了一个日志记录服务 journald 来记录服务单元的日志活动,而查看日志的命令也只有一条,即 journalctl,以下便是关于该命令最常见的用法:
# -------------------- 1. 查看日志 --------------------
# 查看全部日志
journalctl
# 查看当前启动的内核日志
journalctl -k
# 查看指定服务的全部日志
journalctl -u nginx
# 查看最近 N 条日志
journalctl -n 50
# 查看最新日志并自动跳到末尾
journalctl -e
# 实时跟踪日志(类似 tail -f)
journalctl -f
# 显示完整时间等信息
journalctl -o short-full
# -------------------- 2. 按时间查看日志 --------------------
# 查看今天的日志
journalctl --since today
# 查看最近 30 分钟的日志
journalctl --since "30 min ago"
# 查看指定时间之后的日志
journalctl --since "2026-08-11 10:00:00"
# 查看指定时间之前的日志
journalctl --until "2026-08-11 12:00:00"
# 查看指定时间范围的日志
journalctl --since "2026-08-11 10:00:00" --until "2026-08-11 12:00:00"
# 查看某服务最近 1 小时的日志
journalctl -u nginx --since today
# -------------------- 3. 按日志级别过滤 --------------------
# 查看 error 及更严重的日志
journalctl -p err
# 查看 warning 到 emergency
journalctl -p warning..emerg
# 常见日志级别:
#
# 0 emerg 紧急
# 1 alert 必须立即处理
# 2 crit 严重错误
# 3 err 错误
# 4 warning 警告
# 5 notice 注意
# 6 info 信息
# 7 debug 调试
# -------------------- 4. 按关键词搜索 --------------------
# 搜索包含关键字的日志
journalctl -g "error"
# 搜索指定服务中的关键词
journalctl -u nginx -g "error"
# 忽略大小写搜索
journalctl -g "error" --case-sensitive=false
# -------------------- 5. 日志空间占用 --------------------
# 查看 journal 日志占用空间
journalctl --disk-usage
# 删除超过指定时间的日志
journalctl --vacuum-time=30d
5、杂七杂八
(1)参考文档:阮一峰的网络日志、 [ArchWiki ](https://wiki.archlinux.org/title/Systemd_(简体中文)?action = history)、官方手册
(2)systemctl 子命令 daemon-reload 和 reload 的区别 :
| 命令 | 功能 |
|---|---|
systemctl daemon-reload |
让 systemd 重新读取 Unit 配置文件,以便 systemctl 在管理服务的时候能够按照最新的 Unit 配置文件内容做出反应。 |
systemctl reload nginx.service |
让某个正在运行的服务重新加载自己的配置文件,例如:让 nginx 服务重新加载自己的配置文件 nginx.conf 的参数内容。 |
(3)为什么执行开机自启命令 systemctl enable *.service 的时候,命令会在 /etc/systemd/system/multi-user.target.wants/ 目录中添加服务的软链接?
开机自启说白了就是让服务能够跟随 multi-user.target 服务单元一起被启动,而在服务单元 Unit 的配置文件中,这一功能是可以通过参数 Wants 实现的,因此你是可以通过修改 /etc/systemd/system/multi-user.target 配置文件来做到让指定服务开机自启的。
但我们前面也说过,系统预置的 Unit 文件一般不要随便改动。于是官方又为其设计了 /etc/systemd/system/multi-user.target.wants/ 目录,其功能与 Unit 文件中的 Wants 参数的作用是一样的,不用随便修改文件只需把指定服务的软链接放进去就可以,也不用老是在修改完 Unit 文件之后需要频繁执行 systemctl daemon-reload 加载信息,可谓是相当灵活。
注:服务对应的 Unit 文件(此处以 nginx.service 为例)中 [Install] 块下的
WantedBy = multi-user.target是指,当执行systemctl enable nginx.service时,便会为 nginx.service 创建软链接,链接目标便是在 multi-user.target 的 wants 文件夹下面,即/etc/systemd/system/multi-user.target。
(4)Unit 模板单元示例(此处以 vsftpd 为例):
以前,如果我们想运行多个 FTP 实例,那我们会为其配置多个配置文件(如 ftpd1.conf、ftpd2.conf、ftpd3.conf 等),然后按照 vsftpd /etc/vsftpd/ftpd1.conf、vsftpd /etc/vsftpd/ftpd2.conf、vsftpd /etc/vsftpd/ftpd3.conf 的方式去一一启动。
但现在,我们管理服务都是通过 systemd 进行的,那该如何实现通过 systemctl 达到一键开启多个实例的效果呢?这就轮到 Unit 模板单元来展示了。
用法其实也很简单,就是将常规的 vsftpd.service 文件中关于配置文件变动的地方改成变量的形式就好了,如下:
# cat /usr/lib/systemd/system/vsftpd@.service
[Unit]
Description=Vsftpd ftp daemon
After=network.target
PartOf=vsftpd.target
[Service]
Type=forking
ExecStart=/usr/sbin/vsftpd /etc/vsftpd/ftpd%I.conf
#[Install]
#WantedBy=vsftpd.target
# 注意:该配置来自鸟哥私房菜。此处并非是 multi-user.target,而是一个自建的 vsftpd.target,这一点似乎有说法,但我觉得直接注释即可,作用不大。
如此一来,我们想启动 ftpd2.conf 配置文件的实例就执行 systemctl start vsftpd@2.service,想启动 ftpd3.conf 的实例,就执行 systemctl start vsftpd@3.service 。可这样还是有个不方便的地方,那就是如果我们想将三个实例都启动起来,就需要连续执行 3 次启动命令,而且这种模板服务似乎也不能够进行开机自启。
注:在
systemctl start vsftpd@1.service中,@后面的字串会被当做参数赋值给配置文件中的变量%I。
这时候我们就可以用到 target 这个 Unit 了,让它来帮我们实现一键启动多个模板实例的效果。
# cat /usr/lib/systemd/system/vsftpd.target
[Unit]
Description=Test
Requires=vsftpd@1.service vsftpd@2.service vsftpd@3.service
After=vsftpd@1.service vsftpd@2.service vsftpd@3.service
[Install]
WantedBy=multi-user.target
浙公网安备 33010602011771号