首页/系统/Linux 运维命令速查/systemctl enable/disable 开机自启
systemd 与服务42 条

systemctl enable/disable 开机自启

enable 把单元接入启动目标(建软链接),disable 反向拆除;--now 同时启停,is-enabled 核对结果,是最易被想当然的环节。

Linux 运维命令速查系统更新于 2026-10-13

enable 与 disable 是什么

enable 与 disable 管的是开机自启:enable 会在启动目标的 .wants 目录里建立指向单元文件的软链接,让 systemd 在到达该目标时把单元拉起来;disable 则拆除这些链接。它完全不改变单元此刻的运行状态——正在跑的服务 disable 之后继续跑,直到下次重启才不再自启。把这两件事分清,能避免「已经 disable 了为什么还在跑」这类疑问。

基本信息

适用平台Linux(systemd 发行版)
命令语法systemctl enable|disable [--now] [--runtime] 单元...
常用选项--now 同时启动或停止、--runtime 只对当前运行期有效(重启后失效)、-f 覆盖已存在的链接、--user 操作用户级单元
状态取值is-enabled 可能返回 enabled、disabled、static、masked、indirect、generated、enabled-runtime
权限要求系统级单元需要 root 或 sudo;用户级单元用 systemctl --user 无需提权

典型使用场景

  • 部署新服务:确认单元能正常启动后,用 enable --now 一步完成自启与启动
  • 下线服务:disable --now 同时取消自启并停止服务
  • 核对自启清单:is-enabled 与 list-unit-files 快速筛查哪些服务会随开机启动
  • 临时实验:--runtime 只在本次运行期生效,重启自动恢复原状
  • 排查启动顺序:list-dependencies 看某个 target 下会拉起哪些单元
  • 彻底禁用:对不希望被任何依赖拉起的单元使用 mask

常用示例

常用示例
systemctl enable nginx
systemctl enable --now myapp       # 设置自启并立刻启动
systemctl disable firewalld
systemctl disable --now myapp      # 取消自启并停止服务
systemctl is-enabled nginx         # enabled/disabled/static/masked
systemctl enable --runtime nginx   # 只对当前运行期生效
systemctl list-unit-files --state=enabled | head -30
systemctl list-dependencies multi-user.target | head -n 40
systemctl mask telnet.socket; systemctl unmask telnet.socket

is-enabled 取值读法

取值含义处理方式
enabled已建立自启链接开机时会被拉起
disabled无自启链接,但仍可被依赖拉起需要时手动 start
static单元没有 [Install] 段,不能被 enable通常由其他单元或 socket 激活
masked链接到 /dev/null,彻底禁止启动取消需要先 unmask
indirect由某个别名或依赖间接启用需要连同上游单元一起看
generated由生成器动态产生(如 fstab 生成的挂载单元)应修改源配置文件而不是单元本身
disable 与 mask 的强度不同:disable 只是取消自启,服务仍能在被依赖或手工 start 时运行;mask 把单元链接到 /dev/null,任何路径都无法启动它,连依赖它的单元也会因为依赖无法满足而启动失败。需要「彻底不要再被拉起」时使用 mask。另外,socket 激活型服务要连同对应的 .socket 单元一起处理,只 disable 服务单元时端口仍在监听,随时会把服务重新拉起来。
单元文件位置会影响自启结果:同名单元以 /etc/systemd/system 优先于 /usr/lib/systemd/system。把自定义单元放在 /etc 下并 enable 后,如果后来在别处又放了同名文件,容易出现「自启指向的不是我期望的那份定义」,排查时用 systemctl cat 单元名 确认实际加载的路径。巡检自启清单用 systemctl list-unit-files --state=enabled,再配合 list-dependencies 某个 target 看实际会拉起哪些单元。怀疑某服务被意外拉起时,先查它的上级依赖与对应的 .socket,而不是直接改单元定义。实验阶段使用 enable --runtime 只影响当前运行期,重启后自动恢复,能避免留下需要清理的配置。
不要用直接删除软链接或单元文件的方式代替 disable 与 mask:systemd 在内存中保留单元状态,手工操作容易留下不一致的引用;卸载软件后再手工删文件,还可能让残留的 .wants 链接指向不存在的单元,在启动时产生告警。

三种禁止方式的区别

方式效果适用
停止立即停止,开机仍会启动临时停服务
禁用开机不再自启,当前继续运行日常下线
屏蔽彻底禁止启动,依赖它的单元会失败确认不再使用
屏蔽并停止屏蔽同时立即停止彻底禁用
启用状态与运行状态是两件事:前者决定开机与依赖触发时是否拉起,后者是当前这一刻是否在跑。变更流程里两者都要验证,脚本判活也不能只看其中一项,否则会出现「以为停掉了其实还在跑」或反之的误判。

易错点

  • 对 static 单元 enable 会报错,它没有 [Install] 段,通常由其他单元拉起;不要为了启用而随手加 [Install] 段
  • disable 不会停止正在运行的服务,要立即停止需加 --now 或单独执行 stop
  • 把「已 disable」等同于「不会运行」:被其他单元依赖或因 socket 激活时,它仍会启动;彻底禁止要用 mask
  • mask 之后忘记原因,后续排查时以为服务坏了;masked 状态需要先 unmask 才能启动
  • 手工删除软链接代替 disable,可能与 systemd 的内存状态不一致,规范做法是使用命令操作
  • 下线服务只做禁用不做停止:进程继续运行并对外提供服务,从变更流程的视角看像是没执行,实际影响面仍在

数据来源与参考

  • man 1 systemctl(enable/disable/is-enabled)
  • man 5 systemd.unit([Install])

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌