Skip to content

这篇指南咱们来聊聊systemctl命令,这是控制初始化系统的核心工具。 我们会覆盖管理服务、检查状态、更改系统状态,以及处理配置文件。 要了解systemctl 首先就要了解systemd

什么是systemd

systemd是一个用于 Linux 系统的初始化系统(init system)和服务管理器. 负责在系统启动时初始化用户空间、管理服务进程以及系统资源。它是现代 Linux 发行版(如 Ubuntu、Debian、Fedora、Arch Linux 等)中广泛使用的标准组件,取代了传统的 SysVinit 系统。 systemd 作为 PID 1 运行(第一个启动的进程) 负责启动、停止和管理其他所有进程. 注意,虽然systemd已经是很多Linux发行版的默认初始化系统,但不是所有发行版都用它。如果你跟着教程走,终端报错bash: systemctl is not installed,很可能你的机器用的是其他初始化系统。

systemd最重要的就是服务管理

服务管理

systemd用来随时管理服务器上的服务和守护进程。考虑到这点,咱们从基本的服务管理操作开始。

systemd里,大多数操作的目标是“单元”(units),这些是systemd知道怎么管理的资源。单元按类型分类,用单元文件定义。每个单元的类型从文件后缀看出来。

服务管理任务的目标是服务单元,后缀是.service。但大多数服务管理命令,你可以省略.service后缀,因为systemd够聪明,知道你操作服务时很可能就是针对服务。

启动和停止服务

要启动systemd服务,执行服务单元文件里的指令,用start命令。如果你不是root用户,得用sudo,因为这会影响操作系统状态:

bash
sudo systemctl start application.service

如上所述,systemd知道服务管理命令找*.service文件,所以命令可以这么写:

bash
sudo systemctl start application

虽然日常管理可以用上面格式,但为了清楚,咱们剩下命令都用.service后缀,明确操作目标。

要停止正在运行的服务,用stop命令:

bash
sudo systemctl stop application.service

重启和重载

要重启运行中的服务,用restart命令:

bash
sudo systemctl restart application.service

如果应用能重载配置文件(不重启),用reload命令启动这个过程:

bash
sudo systemctl reload application.service

如果你不确定服务能不能重载配置,用reload-or-restart命令。如果能重载,就原地重载;否则,重启服务应用新配置:

bash
sudo systemctl reload-or-restart application.service

启用和禁用服务

上面命令适合当前会话启动或停止服务。要让systemd在开机时自动启动服务,得启用它们。

要开机启动服务,用enable命令:

bash
sudo systemctl enable application.service

这会在磁盘上创建符号链接,从系统的服务文件拷贝(通常在/lib/systemd/system/etc/systemd/system)链接到systemd找自动启动文件的地方(通常/etc/systemd/system/some_target.target.wants,后面会聊target)。

要禁用服务自动启动,用:

bash
sudo systemctl disable application.service

这会移除表示服务自动启动的符号链接。

记住,启用服务不会在当前会话启动它。如果你想启动服务并开机启用,得同时用startenable命令。

检查服务状态

要检查系统上服务的状态,用status命令:

bash
systemctl status application.service

这会显示服务状态、cgroup层次结构,以及前几行日志。

比如,检查Nginx服务器状态,可能看到这样的输出:

Output● nginx.service - A high performance web server and a reverse proxy server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
   Active: active (running) since Tue 2015-01-27 19:41:23 EST; 22h ago
 Main PID: 495 (nginx)
   CGroup: /system.slice/nginx.service
           ├─495 nginx: master process /usr/bin/nginx -g pid /run/nginx.pid; error_log stderr;
           └─496 nginx: worker process
Jan 27 19:41:23 desktop systemd[1]: Starting A high performance web server and a reverse proxy server...
Jan 27 19:41:23 desktop systemd[1]: Started A high performance web server and a reverse proxy server.

这给你当前应用状态的概览,通知任何问题和可能需要的操作。

还有检查特定状态的方法。比如,要检查单元是否活跃(运行中),用is-active命令:

bash
systemctl is-active application.service

这会返回当前单元状态,通常是activeinactive。如果活跃,退出码是“0”,方便shell脚本解析。

要检查单元是否启用,用is-enabled命令:

bash
systemctl is-enabled application.service

这会输出服务是enabled还是disabled,退出码根据答案设为“0”或“1”。

第三个检查是单元是否失败状态,表示启动单元出问题:

bash
systemctl is-failed application.service

如果正常运行,返回active;如果出错,返回failed。如果有意停止,返回unknowninactive。退出码“0”表示失败,“1”表示其他状态。

系统状态概览

到目前为止的命令适合管理单个服务,但探索系统当前状态不太方便。有些systemctl命令提供这些信息。

列出当前单元

要列出systemd知道的所有活跃单元,用list-units命令:

bash
systemctl list-units

这会显示系统上当前活跃的所有单元列表。输出可能像这样:

OutputUNIT                                      LOAD   ACTIVE SUB     DESCRIPTION
atd.service                               loaded active running ATD daemon
avahi-daemon.service                      loaded active running Avahi mDNS/DNS-SD Stack
dbus.service                              loaded active running D-Bus System Message Bus
dcron.service                             loaded active running Periodic Command Scheduler
dkms.service                              loaded active exited  Dynamic Kernel Modules System
getty@tty1.service                        loaded active running Getty on tty1
.
.
.

输出有这些列:

  • UNITsystemd单元名称。
  • LOAD:单元配置是否加载到systemd。除了错误,大多数时候是loaded
  • ACTIVE:高层次的单元激活状态。activeinactive等。
  • SUB:低层次的状态,取决于单元类型、进程等。
  • DESCRIPTION:单元的简短描述。

默认只显示活跃单元。要显示所有单元,不管状态,用--all标志:

bash
systemctl list-units --all

--state=参数显示特定状态的单元。--state=可以是loadactiveinactiveenableddisabledstaticgenerated等。

另一个选项是--type=,显示特定类型的单元,比如--type=service--type=target

列出单元文件

上面命令显示systemd当前内存中的单元。要看所有单元文件(不管是否活跃),用list-unit-files

bash
systemctl list-unit-files

这会列出所有单元文件及其状态,比如enableddisabledstatic(不可启用)、indirectgeneratedtransient

要看特定类型单元文件,用--type=,比如只看服务单元文件:

bash
systemctl list-unit-files --type=service

单元管理

到目前为止,我们看到的命令大多是管理单个单元的快捷方式。咱们也可以用systemctl的通用命令处理所有这些事儿。

比如,startstopreloadrestart对应通用命令isolatehaltpoweroffreboot,但服务管理常用快捷方式。

要显示单元文件内容,用cat命令(systemd v209新增):

bash
systemctl cat application.service

要看单元依赖,用list-dependencies

bash
systemctl list-dependencies application.service

这会显示递归依赖树。只看目标单元,用--plain

编辑单元文件

要编辑单元文件,用edit命令,创建覆盖片段:

bash
sudo systemctl edit application.service

要编辑整个单元文件,用--full

bash
sudo systemctl edit --full application.service

编辑后,重载systemd守护进程应用变化:

bash
sudo systemctl daemon-reload

用屏蔽防止启动

要防止服务启动,用mask命令,创建符号链接到/dev/null

bash
sudo systemctl mask application.service

这会阻止服务启动,即使间接。

要取消屏蔽,用unmask

bash
sudo systemctl unmask application.service

调整系统状态

systemctl不只管理服务,还能调整系统状态。

显示当前状态

要看系统状态,用show命令,加上--system--user

bash
systemctl show --system

这会显示键值对形式的系统属性。

要看特定属性,用--property

bash
systemctl show --property=ActiveState --system

更改系统状态

系统状态用target表示,target是单元组,定义系统状态。

要列出可用target,用:

bash
systemctl list-unit-files --type=target

要列出活跃target,用:

bash
systemctl list-units --type=target

要更改当前target,用isolate

bash
sudo systemctl isolate multi-user.target

这会停止非必要单元,只剩multi-user.target及其依赖。

常见target包括multi-user.target(默认多用户无图形)、graphical.target(多用户带图形)、rescue.target(单用户恢复)、emergency.target(紧急壳)、halt.targetpoweroff.targetreboot.target

要关机,用:

bash
sudo systemctl halt
sudo systemctl poweroff
sudo systemctl reboot

要挂起、休眠、混合,用:

bash
sudo systemctl suspend
sudo systemctl hibernate
sudo systemctl hybrid-sleep

获取和设置默认target

要看默认target,用:

bash
systemctl get-default

要设置默认target,用:

bash
sudo systemctl set-default multi-user.target

这会创建符号链接/etc/systemd/system/default.target指向指定target。

查看日志条目

systemdjournald收集日志,用journalctl查看。

要看所有日志,用:

bash
sudo journalctl

要看特定单元日志,用-u

bash
sudo journalctl -u application.service

要看内核日志,用-k

bash
sudo journalctl -k

要看最近日志并跟随,用-f

bash
sudo journalctl -f

要看时间范围日志,用--since--until

更多选项见journalctl手册。

常见错误和调试

“Failed to start unit”或“Unit not found”错误

遇到这些错误,检查服务文件是否存在和正确。确保文件在正确目录如/etc/systemd/system//lib/systemd/system/,文件名和后缀正确(比如httpd.service)。检查语法错误或依赖问题。

配置服务文件时,放对地方。系统服务配置在/lib/systemd/system/,自定义或覆盖在/etc/systemd/system/,确保自定义优先。

检查服务文件位置和语法,用:

bash
sudo systemctl status httpd
sudo systemctl cat httpd

第一个命令显示状态,包括错误消息。第二个显示文件内容,检查语法和依赖。

权限问题(比如需要sudo)

管理服务需权限不足时出问题。用sudo运行systemctl命令,尤其是修改系统文件或需提升权限的操作。

比如,重载httpd服务:

bash
sudo systemctl reload httpd

错位或无效单元文件

错位或无效单元文件导致管理错误。确认单元文件在/etc/systemd/system//lib/systemd/system/,格式正确。自定义单元文件命名和语法正确。

验证单元文件位置和格式,用:

bash
sudo systemctl list-unit-files
sudo systemctl cat <service_name>

第一个列出所有单元文件及其状态。第二个显示特定单元文件内容,检查格式和语法。

常见问题

1. Linux中systemctl是干啥的?

systemctl是命令行工具,用来管理和交互Linux的systemd系统和服务管理器。能启动、停止、重启、启用、禁用服务,以及检查状态。

2. 怎么启动或停止systemd服务?

启动用start加服务名。比如启动httpd

bash
sudo systemctl start httpd

停止用stop

bash
sudo systemctl stop httpd

3. systemctl enable是干啥的?

enable让服务开机自动启动。比如启用httpd

bash
sudo systemctl enable httpd

这在/etc/systemd/system创建符号链接,表示开机启动。

4. 怎么检查服务是否运行?

status加服务名。比如检查httpd

bash
sudo systemctl status httpd

显示当前状态,包括是否运行。

5. systemctl中restart和reload有啥区别?

restart停止然后启动服务,实际重载配置。比如重启httpd

bash
sudo systemctl restart httpd

reload不停止服务,只重载配置。改配置文件想应用变化又不中断服务时用。比如重载httpd

bash
sudo systemctl reload httpd

结语

现在,你应该熟悉systemctl的一些基本功能,能交互和控制systemd实例。systemctl是服务和系统状态管理的主要工具。

虽然systemctl主要操作核心systemd进程,但systemd生态还有其他组件,用其他工具控制。比如日志管理和用户会话用journald/journalctllogind/loginctl。花时间熟悉这些工具,能让管理更轻松。

想进一步学习,推荐这些资源: