我们如何屏蔽单元文件位于 /etc/systemd/system 下的服务?

我们如何屏蔽单元文件位于 /etc/systemd/system 下的服务?

我在 /etc/systemd/system 下创建了一个测试服务,这是创建自定义单元文件的正确路径。

[root@apollo system]# cat sample.service
[Unit]
Description=This is my test service
Wants=chronyd.service
After=chronyd.service

[Service]
Type=forking
ExecStart=/root/sample.sh

[Install]
WantedBy=multiuser.target chronyd.service
#RequiredBy=multiuser.target chronyd.service
#Alias=xyz
[root@apollo system]# pwd
/etc/systemd/system
[root@apollo system]#

我通过运行“systemctl daemon-reload”来确保 systemd 知道。我还能够停止/启动该服务。

当我尝试屏蔽它时,它向我显示以下错误:

[root@apollo system]# systemctl mask sample.service
Failed to execute operation: File exists
[root@apollo system]#

这是因为 systemd 正在尝试使用以下命令创建符号链接:

ln -s /dev/null /etc/systemd/system/sample.service

由于 Sample.service 已存在于 /etc/systemd/system 中,因此除非 systemd 使用“ln -fs”,否则该命令将失败。

这意味着我们不能屏蔽在 /etc/systemd/system 下创建的任何单元文件?

我尝试将 example.service 移动到 /usr/lib/systemd/system 并且能够屏蔽它,因为它能够在 /etc/systemd/system 下创建符号链接而没有任何阻碍。

有人经历过这个吗?您认为这是一个错误吗?

答案1

/etc/systemd/system如果不先从其中删除文件,就无法屏蔽包含服务文件的服务。这是有意的设计。

禁用在许多情况下,使用它的服务systemctl disable servicename.service与屏蔽它具有相同的效果。

systemd 作者的帖子三个关闭级别有关 systemd 中stopdisable和之间的差异的更多详细信息。mask

答案2

马克·斯托斯伯格接受的答案是完全正确的,并且很高兴获得投票:这在设计上是不可能的。但我同意暂时屏蔽您自己的服务可能一生中一次有用 - 例如,在调试时,或者因为某个硬件暂时无法正常工作。

但自从无休止的讨论是无止境的,如果做不到就伪造它:重命名your.serviceyour.service.maskedsystemctl daemon-reload这样做,以便 systemd 注意到。唯一的缺点是该服务根本没有报告,而是存在但被屏蔽了。

$ sudo mv -v /etc/systemd/system/dpkg-daily.service{,.masked}
renamed '/etc/systemd/system/dpkg-daily.service' -> '/etc/systemd/system/dpkg-daily.service.masked'
$ sudo systemctl daemon-reload
$ journalctl -n5
 . . .
Oct 06 18:31:16 [previous irrelevant message, logged 5.5 hours ago...
                 ... systemd itself is totally nonchalant about something ending in .masked ...]
Oct 06 23:53:57 buba systemd[1]: Reloading.
$ systemctl status dpkg-daily.service
Unit dpkg-daily.service could not be found. <== If you can live with that...

...以及失败的依赖关系 - 但他们仍然会失败如果该单位无论如何都被掩盖了。请注意,您没有理由屏蔽服务,除非它作为其他单元的依赖项启动 - 在这种情况下只需禁用它,正如已接受的答案中所建议的那样。

$ sudo mv -v /etc/systemd/system/dpkg-daily.service{.masked,}
renamed '/etc/systemd/system/dpkg-daily.service.masked' -> '/etc/systemd/system/dpkg-daily.service'
$ sudo systemctl daemon-reload
$ systemctl status dpkg-daily.service
● dpkg-daily.service - Daily dpkg database backup
     Loaded: loaded (/etc/systemd/system/dpkg-daily.service; static)
     Active: inactive (dead) since Fri 2023-10-06 00:00:07 PDT; 24h ago
TriggeredBy: 

答案3

警告:
正如评论中提到的,不建议在/lib目录中进行更改。但是,如果您正在处理本地问题,则可以考虑此解决方案。就我而言,我不希望任何人意外运行服务,因此我使用了这种方法并且没有破坏任何东西。


如果您决定屏蔽该服务,则必须将设备的配置文件移动到/lib/systemd/system.

sudo mv /etc/systemd/system/sample.service /lib/systemd/system/

之后你就可以运行:

sudo systemctl mask sample.service

这将在 中创建一个符号链接/etc/systemd/system/sample.service

相关内容