问题1:服务状态查询
查看所有被 mask 的服务
systemctl list-unit-files | grep masked
或更详细的查看
systemctl list-unit-files --state=masked
查看所有服务状态,并过滤 masked
systemctl list-units --type=service --all | grep masked
查看所有失败的服务
sudo systemctl --failed
查看所有服务的状态(失败的服务会标记为红色或 FAILED)
systemctl list-units --type=service --all
列出所有已加载的服务单元文件
systemctl list-unit-files --type=service
列出所有单元(包括服务、socket、timer等)
systemctl list-units --all
查找特定服务
systemctl list-unit-files --type=service --all | grep nginx
只查看错误状态的服务
systemctl list-units --type=service --state=failed
查看所有活跃(正在运行)的服务
systemctl list-units --type=service --state=running
简写版本
systemctl list-units --type=service | grep running
带详细信息的完整列表
systemctl list-units --type=service --all
查看依赖关系
systemctl list-dependencies servicename
systemctl list-dependencies --reverse servicename # 反向依赖
systemctl status servicename # 详细状态
systemctl is-active servicename # 是否活跃
systemctl is-enabled servicename # 是否启用
systemctl is-failed servicename # 是否失败
systemctl show servicename # 显示所有属性
快速参考命令
查找服务位置
systemctl show SERVICE -p FragmentPath
临时启动任意脚本作为服务
sudo systemd-run --unit=temporary-service /path/to/script
创建并启用自定义服务
sudo cp custom.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable custom.service
sudo systemctl start custom.service
禁用并删除
sudo systemctl stop custom.service
sudo systemctl disable custom.service
sudo rm /etc/systemd/system/custom.service
sudo systemctl daemon-reload
问题2:如何让system服务A在服务B之后运行?
使用 After= 和 Before= 指令,服务A的 .service 文件中添加:
Unit
Description=服务A
After=服务B.service # 确保在服务B之后启动
Before=服务C.service # 确保在服务C之前启动
Requires=服务B.service # 依赖服务B(如果B失败,A也会失败)
Wants=服务B.service # 希望依赖服务B(如果B失败,A仍会启动)
问题3:service如果不在常规的位置,如何启动?
1. 系统级服务文件位置(优先级从高到低)
最高优先级:运行时配置(临时生效)
/etc/systemd/system/*.service # 管理员自定义服务
第二优先级:安装包配置
/run/systemd/system/*.service # 运行时生成的服务
第三优先级:系统默认配置
/lib/systemd/system/*.service # 发行版提供的服务(/usr/lib/systemd/system/ 的符号链接)
实际安装位置(新系统)
/usr/lib/systemd/system/*.service # 软件包安装的服务
2. 用户级服务文件位置
用户自定义服务(优先级高)
~/.config/systemd/user/*.service # 用户配置目录
$XDG_CONFIG_HOME/systemd/user/*.service
系统提供的用户服务
/usr/lib/systemd/user/*.service # 系统级用户服务
3. 检查服务的实际位置
查找特定服务的文件
systemctl show ssh.service -p FragmentPath
或使用
systemctl status ssh.service | grep "Loaded:"
输出示例:Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
使用 find 命令查找
sudo find / -name "*.service" -type f 2>/dev/null | grep ssh
查看服务文件的来源
dpkg -S ssh.service
使用 systemctl 的链接功能
# 创建符号链接到标准目录
sudo mkdir -p /etc/systemd/system
sudo ln -sf /custom/path/myservice.service /etc/systemd/system/
# 重新加载 systemd 配置
sudo systemctl daemon-reload
# 现在可以正常管理
sudo systemctl start myservice.service
sudo systemctl enable myservice.service
用户级自定义服务
1. 创建用户服务目录
mkdir -p ~/.config/systemd/user/
2. 创建服务文件
cat > ~/.config/systemd/user/my-user-service.service << EOF
Unit
Description=My User Service
Service
Type=oneshot
ExecStart=/usr/bin/touch /tmp/user-service-test
Install
WantedBy=default.target
EOF
3. 重新加载用户级 systemd
systemctl --user daemon-reload
4. 启动用户服务
systemctl --user start my-user-service.service
服务在非标准路径
# 假设服务文件在 /opt/myapp/myapp.service
# 方法A:创建符号链接
sudo ln -s /opt/myapp/myapp.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl start myapp
# 方法B:使用绝对路径直接管理
sudo systemctl link /opt/myapp/myapp.service
sudo systemctl enable /opt/myapp/myapp.service
sudo systemctl start myapp
关键点
-
删除 ≠ 停止:删除文件不会停止正在运行的服务
-
停止 ≠ 禁用:停止服务只是当前停止,重启后可能再次启动
-
禁用 ≠ 屏蔽:禁用可以被其他服务重新激活,屏蔽是最高级别禁用
-
重新加载 :修改服务文件后必须执行
daemon-reload
问题4:systemctl mask是如何工作的?
systemctl mask 报错 "already exists"
为什么有了对应的service文件后,再mask就会报错: xx.service already exists?
1. systemctl mask 本质上是在 /etc/systemd/system/ 目录下创建一个指向 /dev/null 的符号链接
2. 优先级机制systemd加载服务文件的优先级顺序:
1. /etc/systemd/system/ # 优先级最高
2. /run/systemd/system/ # 运行时配置
3. /usr/lib/systemd/system/ # 软件包安装的默认配置
当存在 /etc/systemd/system/ssh.service(即使是符号链接)时,systemd 会优先使用它,而忽略 /usr/lib/systemd/system/ssh.service。
- mask 的效果
-
阻止服务启动(手动或自动)
-
阻止服务被依赖
-
但仍然可以查看状态(会显示 "masked")
-
mask 和 disable 的区别:
-
disable:移除自动启动,但可以手动启动 -
mask:完全禁止启动(手动和自动)
方法1:直接删除已有文件,然后 mask
sudo rm /etc/systemd/system/xxx.service
sudo systemctl mask xxx.service
方法2:使用强制覆盖(推荐)
systemd 239+ 版本支持 --force
sudo systemctl mask --force xxx.service
问题5:任务启动失败,怎么查看原因?
- 查看服务状态(最常用)
sudo systemctl status xx.service
- 查看详细的日志
# 查看完整日志(实时)
sudo journalctl -u virtual-display.service -f
# 查看今天的所有日志
sudo journalctl -u virtual-display.service --since today
# 查看最近50条日志
sudo journalctl -u virtual-display.service -n 50
# 查看更详细的日志(包括调试信息)
sudo journalctl -u virtual-display.service -xe
# 按时间倒序显示
sudo journalctl -u virtual-display.service --reverse
- 查看服务启动过程
# 查看启动顺序依赖
sudo systemctl list-dependencies virtual-display.service
# 检查服务配置
sudo systemctl cat virtual-display.service
# 1. 停止服务
sudo systemctl stop virtual-display.service
# 2. 启用调试日志
sudo journalctl --vacuum-time=1d # 清理旧日志
sudo systemctl daemon-reload
# 3. 启动服务
sudo systemctl start virtual-display.service
# 4. 立即查看状态
sudo systemctl status virtual-display.service
# 5. 查看详细日志
sudo journalctl -u virtual-display.service -f
# 6. 检查端口
sudo netstat -tlnp | grep :59