为什么有些systemd服务处于“masked”状态?

当我运行命令sudo systemctl list-unit-files(我认为sudo是可选的)时,我会得到一个显示所有服务及其状态的输出。
这是我机器上的一小段内容:
UNIT FILE                                  STATE
...
debian-fixup.service                       static  
debug-shell.service                        disabled
display-manager.service                    enabled 
dns-clean.service                          enabled 
dsmcad.service                             enabled 
emergency.service                          static  
failsafe-x.service                         static  
friendly-recovery.service                  masked  
fuse.service                               masked  
gdm.service                                masked  
getty-static.service                       static  
getty@.service                             enabled 
gpsd.service                               indirect
gpsdctl@.service                           static  
gpu-manager.service                        enabled 
halt-local.service                         static  
halt.service                               masked  
hostname.service                           masked
...

我想知道为什么有些服务处于“屏蔽”状态。我认为这意味着“这比‘禁用’更好,因为无论是手动还是通过systemd都无法启动该服务”。
如何获取有关服务单元状态的更多信息?
是谁将这些单元放入了各自的状态中?
例如,我尝试了以下命令: sudo systemctl help dsmcad - 这只会显示来自单元文件的documentation = ...行。/etc/systemd/system/dsmcad.service 注意:在这里,我非常清楚dsmcad服务是什么以及它的作用,我自己安装了它。我更感兴趣的是一个通用解决方案。
4个回答

maskdisable的更强版本。使用disable将删除指定单元文件的所有符号链接。如果使用mask,这些单元将链接到/dev/null。如果您通过systemctl status halt.service进行检查,将显示此信息。 mask的优点是可以防止任何类型的激活,甚至是手动激活。

注意:systemctl list-unit-files列出的是单位文件的状态(静态、已启用、已禁用、已屏蔽、间接屏蔽),与服务的状态无关。要查看服务的状态,请使用systemctl list-units


19如果需要的话,请您也说明如何解除遮罩状态。 - erikbstack
37有一个maskunmask命令可以与systemctl一起使用。所以只需执行systemctl unmask name_of_service.service即可。 - Kellerspeicher
3执行systemctl unmask name_of_service.service命令会完全从/etc/systemd/system/目录中删除我的服务定义文件,所以现在我需要重新添加它。如果它再次被屏蔽,我将陷入一个循环中。 - Eldamir
3嗨Eldamir,在/etc/systemd/system中只有服务的符号链接。你应该将*.service文件添加到/lib/systemd/system,然后如果你enable这个服务,它会被链接到/etc/systemd/systemmask是创建一个指向/dev/null的链接,而unmask则是从/etc/systemd/system中删除此链接,显然,如果有人在那里放置一个文件,这没有任何区别。 - Kellerspeicher

'mask'是一种单元文件的状态,被视为"关闭的第三级"(停止-第一级,禁用-第二级,屏蔽-第三级)。被标记为屏蔽的服务既不能通过手动启动(使用start命令),也不能由系统在系统启动时启动。因此,在使用systemctl mask命令屏蔽服务时,请谨慎操作。

由于您正在请求有关掩码状态的信息,因此重要的是要提到,在启动后对其定义进行修改并重新加载(systemctl daemon-reload)后,可以在服务中观察到新状态不正常的情况。 一个简单的例子来理解这一点是以下场景:
a) the service is running well (already started)
b) edit the service definition file and delete everything in its contents
c) reload
d) state masked will be observed too

因此,遮蔽状态可能源于不正确的服务定义。因此,用户可能通过不正确地编辑服务来引发未遮蔽状态。
观察:我不确定这是故意还是简单的错误(默认选项),但这可能是一些有趣的信息可以分享。

由于systemd在启动过程中非常早就设置了主机名(从/etc/hostname获取),所以hostname.service被标记为冗余。
这个设置由Debian systemd软件包提供。
$ ls -l /lib/systemd/system/hostname.service
lrwxrwxrwx 1 root root 9 Apr  8 22:47 /lib/systemd/system/hostname.service -> /dev/null
$ dpkg-query --search /lib/systemd/system/hostname.service
systemd: /lib/systemd/system/hostname.service

同样,Debian现在可以在没有shell脚本的情况下运行以停止系统,而是通过systemd-shutdown(源代码这里)来处理。

如果服务被手动屏蔽,该屏蔽将安装在/etc/systemd/system中。

当在Debian/Ubuntu上移除服务时,也会被屏蔽。我不知道为什么。


1遮蔽与移除服务之间的区别在于移除与清除软件包。在第一种情况下,配置文件被保留,因此错误激活服务可能具有潜在危险(因为服务文件可能仍然存在于配置文件中)。清除的软件包也会删除服务文件而不是遮蔽。 - FelixJN