0 前言
systemd是Linux系统的一组基本构建块,它提供了一个PID为1的系统和服务管理器,并启动了系统的其余部分。 systemd提供了积极的并行化功能,使用套接字和D-Bus激活来启动服务,按需启动守护程序,使用Linux控制组跟踪进程,维护安装和自动挂载点,并实现了详细的基于事务依赖关系的服务控制逻辑。systemd支持SysV和LSB初始化脚本,并且可以替代sysvinit[4]。
1 安装
1.1 命令
sudo apt-get install -y systemd
1.2 源码
(1)下载
可到gitee下载源码。
(2)编译
sudo apt-get install -y meson gperf libcap-dev cmake libmount-dev
cd systemd
# 方法1
./configure
make -j`nproc`
sudo make install
# 方法2
meson build
ninja -C build
sudo ninja -C build install
1.3 版本
可通过下面命令查看systemd版本:
systemd --version
2 进程
有两个systemd进程,其中一个是1号进程(PID=1),另一个是普通进程。
3 配置
每个服务都是用一个独立的xxx.service文件定义,通常位于如下目录:
/etc/systemd/[system|user].conf | DefaultRestartSec=100ms |
/etc/systemd/[system|user] | 其中的xxx.service是通常是/lib/systemd/[system|user]/xxx.service的软链接 |
/lib/systemd/[system|user] | 各xxx.service的真正存储位置 |
/run/systemd | /run/systemd/sessions/<数字序号>,包含了该登录会话的用户名,UID,DISPLAY等信息!每个登录都会有一个对应的数字序号,ssh登录的,可以从中看得出来的! |
4 命令
4.1 普通
(1)列出所有服务[9]
systemctl list-units --type=service
systemctl --type=service
systemctl --user/system -t target/service
(2)状态
systemctl is-enabled <service> # 查看服务是否是能
systemctl status <service> # 查看服务状态,关闭/使能服务 # [12]
(3)使能/关闭
systemctl is-enabled <service> # 查看服务是否是能
systemctl disable/enable/stop/start/restart <service> # 查看服务状态,关闭/使能服务 # [12]
systemctl disable/enable/stop/start/restart <service> # 查看服务状态,关闭/使能服务 # [12]
# stop - 立即停止服务,重启恢复
# disable - 重启后禁用服务
systemctl mask/unmask <service>
# mask: Created symlink /etc/systemd/system/laptop-mode.service → /dev/null
其中enable/disable命令的作用就是增加/删除“/lib/systemd/[system|user]/xxx.service”到“/etc/systemd/[system|user]/xxx.service”的软链接,例如:
sudo systemctl enable ssh
# Synchronizing state of ssh.service with SysV service script with /lib/systemd/systemd-sysv-install.
# Executing: /lib/systemd/systemd-sysv-install enable ssh
# Created symlink /etc/systemd/system/sshd.service → /lib/systemd/system/ssh.service.
# Created symlink /etc/systemd/system/multi-user.target.wants/ssh.service → /lib/systemd/system/ssh.service.
sudo systemctl disable gdm.service
# Removed /etc/systemd/system/display-manager.service.
(4)依赖
systemctl --user list-dependencies default.target # [40]
(5)重新加载
修改.service文件后,需要执行下面命令重新加载:
systemctl daemon-reload
4.2 性能
systemd-analyze # 查看系统启动总体时间[15]
systemd-analyze blame # 查看各服务启动时间[15]
# 系统服务
systemd-analyze critical-chain NetworkManager-wait-online.service # 查看服务启动流程[15]
# 用户服务
systemd-analyze --user critical-chain xxx.service
systemd-analyze plot > /tmp/map.svg # 生成矢量图[15]
5 开机启动
Ubuntu16.04以前可在“/etc/rc.local”中添加需要开机启动的命令,然而Ubuntu18.04用systemd取代inited,开机启动项的设置也随之发生变化。
5.1 默认启动
可通过下面命令查看、设置开机默认启动的服务:
systemctl get-default # [20]
sudo systemctl set-default graphical.target # 开机进入图形界面。
sudo systemctl set-default multi-user.target # 开机进入字符终端[13]
上述命令的作用就是分别创建如下软链接:
/etc/systemd/system/default.target -> /lib/systemd/system/graphical.target
# or
/etc/systemd/system/default.target -> /lib/systemd/system/multi-user.target
不同发行版版的默认值如下:
发行版 | 默认值 | 说明 |
Ubuntu(桌面版) | graphical.target | 启动显示管理器 |
UOS(桌面版) | ||
银河麒麟(桌面版) | ||
openEuler(只有服务版) | multi-user.target | 进入字符终端 |
(1)graphical.target
[Unit]
Description=Graphical Interface
Documentation=man:systemd.special(7)
Requires=multi-user.target
Wants=display-manager.service
Conflicts=rescue.service rescue.target
After=multi-user.target rescue.service rescue.target display-manager.service
AllowIsolate=yes
# @file(ubuntu22.04): /usr/lib/systemd/system/graphical.target
可见它的“Wants”为“display-manager.service”,应该是要启动显示管理器,它其实是gdm3.service的软链接:
/etc/systemd/system/display-manager.service -> /lib/systemd/system/gdm3.service # [12]
(2)multi-user.target
[Unit]
Description=Multi-User System
Documentation=man:systemd.special(7)
Requires=basic.target
Conflicts=rescue.service rescue.target
After=basic.target rescue.service rescue.target
AllowIsolate=yes
# @file(ubuntu22.04): /usr/lib/systemd/system/multi-user.target
5.2 兼容“/etc/rc.local”
systemd依然是可以兼容“/etc/rc.local”的[43],例如开发板开机串口提示:
Starting /etc/rc.local Compatibility...
5.3 GUI应用开机启动
(1)Ubuntu
Ubuntu20.04添加了开机启动应用的支持[11],天翼云桌面就是通过该方式设置自动启动的。
(2)UOS
详见参考资料[43]。
6 服务
主要有system和user两种服务,它们分别位于如下目录:
system | /usr/lib/systemd/system | system服务的原始目录,需要链接到下面目录才生效 |
/etc/systemd/system | 基本都是来自上面目录的软链接,代表当前生效的服务 | |
user | /usr/lib/systemd/user | user服务的原始目录,需要链接到下面目录才生效 |
/etc/systemd/user | sudo systemctl --global enable xxx.service会在该目录创建软链接。[39] | |
~/.config/systemd/user | systemctl --user enable xxx.service会在该目录创建软链接。 | |
~/.local/share/systemd/user |
(1)环境变量
system和user两种服务的默认环境变量是不同的:
systemctl --user show-environment
systemctl --system show-environment
其中user类型服务可执行X命令,而system服务则需要配置DISPLAY和XAUTHORITY环境变量才可以[33]。
一个服务主要由Unit、Service、Install和Timer四个部分组成,其中后两个部分是可选的:
[Unit]
Description=OpenBSD Secure Shell server
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target auditd.service
ConditionPathExists=!/etc/ssh/sshd_not_to_be_run
[Service]
EnvironmentFile=-/etc/default/ssh
ExecStartPre=/usr/sbin/sshd -t
ExecStart=/usr/sbin/sshd -D $SSHD_OPTS
ExecReload=/usr/sbin/sshd -t
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartPreventExitStatus=255
Type=notify
RuntimeDirectory=sshd
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
Alias=sshd.service
# @file: /usr/lib/systemd/system/ssh.service
6.1 注意
必须正确设置“WantedBy”,否则无法自启动服务,可通过下面命令查看user的WantedBy支持哪些值[40]:
systemctl --user -t target
# UNIT LOAD ACTIVE SUB DESCRIPTION
# basic.target loaded active active Basic System
# default.target loaded active active Default
# paths.target loaded active active Paths
# sockets.target loaded active active Sockets
# timers.target loaded active active Timers
#
# LOAD = Reflects whether the unit definition was properly loaded.
# ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
# SUB = The low-level unit activation state, values depend on unit type.
#
# 5 loaded units listed. Pass --all to see loaded but inactive units, too.
systemctl --system -t target
# UNIT LOAD ACTIVE SUB DESCRIPTION
# basic.target loaded active active Basic System
# cryptsetup.target loaded active active Local Encrypted Volumes
# getty.target loaded active active Login Prompts
# graphical.target loaded active active Graphical Interface
# local-fs-pre.target loaded active active Local File Systems (Pre)
# local-fs.target loaded active active Local File Systems
# multi-user.target loaded active active Multi-User System
# network-online.target loaded active active Network is Online
# network.target loaded active active Network
# nfs-client.target loaded active active NFS client services
# nss-user-lookup.target loaded active active User and Group Name Lookups
# paths.target loaded active active Paths
# remote-fs-pre.target loaded active active Remote File Systems (Pre)
# remote-fs.target loaded active active Remote File Systems
# rpcbind.target loaded active active RPC Port Mapper
# slices.target loaded active active Slices
# sockets.target loaded active active Sockets
# sound.target loaded active active Sound Card
# swap.target loaded active active Swap
# sysinit.target loaded active active System Initialization
# time-sync.target loaded active active System Time Synchronized
# timers.target loaded active active Timers
#
# LOAD = Reflects whether the unit definition was properly loaded.
# ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
# SUB = The low-level unit activation state, values depend on unit type.
#
# 22 loaded units listed. Pass --all to see loaded but inactive units, too.
# To show all installed unit files use 'systemctl list-unit-files'.
6.2 重启
(1)重启间隔
默认自动重启时间间隔为100ms
DefaultRestartSec=100ms # 该配置默认是注释掉的,没有配置,默认就是100ms!
# @file1: /etc/systemd/user.conf
# @file2: /etc/systemd/system.conf
每个服务可以设置自己的重启间隔
RestartSec=100ms
# @file: xxx.service
参考资料
[1]man systemd.service
[2]man systemd.exec
[3]Ubuntu10.04系统服务与开机启动
[4]在Ubuntu 18.04 中设置开机自动执行脚本
[6]Ubuntu20.04开机自启
[7]Ubuntu 20.04 systemd 开机启动项
[8]CentOS8安装GNOME3桌面并设置开机启动图形界面
[9]systemctl命令列出所有服务
[10]Linux Ubuntu 20.04 —添加开机启动(服务/脚本)
[11]Startup Applications
[12]ubuntu下图形程序自启动的几种方法
[13]Ubuntu默认启动到字符界面
[14]linux系统服务(systemctl)的使用
[15]linux 分析启动时服务时间消耗
[16]配置使用systemd管理服务
[17]Linux系统服务管理 系统服务
[18]systemd 简记
[19]linux添加自定义服务 xxx.service
[20]Systemd 入门教程:命令篇
[21]学会爱上 systemd | Linux 中国
[22]systemd 代码已超 120 万行!五年间翻了一番 | Linux 中国
[23]交叉编译 systemd(to be continued)
[24]shell脚本添加到systemd中,设置为开机自启
[25]使用Systemd把自作脚本服务化(加入开机启动)
[26]Systemd 添加自定义服务(开机自启动)
[27]Linux服务管理神器:SYSTEMD介绍
[28]linux系统编写Systemd Service方法
[29]Systemd添加.service服务并设置开机启动
[30]如何优雅的使用 Systemd 管理服务
[31]使用systemd配置一个服务再开机后5分钟再启动
[32]最简明扼要的 Systemd 教程,只需十分钟
[33]Systemd run script after GUI is ready?
[34]Running a user systemd service after the desktop becomes
[35]How to start a systemd service after user login and stop it before user logout
[36]How to set a systemd unit to start after loading the desktop?
[37]Setting DISPLAY in systemd service file
[38]普通用户添加systemd的开机启动项
[39]systemd/User
[40]systemd --user services are not starting automatically #2690
[41]ubuntu 18.04 配置 rc.local
[42]systemd:初学者如何理解其中的争议
[43]Linux开机自动启动
[44]How can I start a shell if booting fails?
[46]单独编译systemd
[47]linux 系统进程管理工具systemd(systemctl命令、创建自己的systemd服务、单位类型Type=notify和Type=forking的区别)
[2]man systemd.exec
[3]Ubuntu10.04系统服务与开机启动
[4]在Ubuntu 18.04 中设置开机自动执行脚本
[6]Ubuntu20.04开机自启
[7]Ubuntu 20.04 systemd 开机启动项
[8]CentOS8安装GNOME3桌面并设置开机启动图形界面
[9]systemctl命令列出所有服务
[10]Linux Ubuntu 20.04 —添加开机启动(服务/脚本)
[11]Startup Applications
[12]ubuntu下图形程序自启动的几种方法
[13]Ubuntu默认启动到字符界面
[14]linux系统服务(systemctl)的使用
[15]linux 分析启动时服务时间消耗
[16]配置使用systemd管理服务
[17]Linux系统服务管理 系统服务
[18]systemd 简记
[19]linux添加自定义服务 xxx.service
[20]Systemd 入门教程:命令篇
[21]学会爱上 systemd | Linux 中国
[22]systemd 代码已超 120 万行!五年间翻了一番 | Linux 中国
[23]交叉编译 systemd(to be continued)
[24]shell脚本添加到systemd中,设置为开机自启
[25]使用Systemd把自作脚本服务化(加入开机启动)
[26]Systemd 添加自定义服务(开机自启动)
[27]Linux服务管理神器:SYSTEMD介绍
[28]linux系统编写Systemd Service方法
[29]Systemd添加.service服务并设置开机启动
[30]如何优雅的使用 Systemd 管理服务
[31]使用systemd配置一个服务再开机后5分钟再启动
[32]最简明扼要的 Systemd 教程,只需十分钟
[33]Systemd run script after GUI is ready?
[34]Running a user systemd service after the desktop becomes
[35]How to start a systemd service after user login and stop it before user logout
[36]How to set a systemd unit to start after loading the desktop?
[37]Setting DISPLAY in systemd service file
[38]普通用户添加systemd的开机启动项
[39]systemd/User
[40]systemd --user services are not starting automatically #2690
[41]ubuntu 18.04 配置 rc.local
[42]systemd:初学者如何理解其中的争议
[43]Linux开机自动启动
[44]How can I start a shell if booting fails?
[46]单独编译systemd
[47]linux 系统进程管理工具systemd(systemctl命令、创建自己的systemd服务、单位类型Type=notify和Type=forking的区别)