systemd:停止所有未安装的单元

systemd:停止所有未安装的单元

我安装并运行了一些 systemd 单元。假设我手动卸载foo.service

  • 删除其 .service (和 .socket)文件
  • 删除所有符号链接(例如从 default.target.wants/)

我可以运行systemctl daemon-reload,然后我看到:

# systemctl status foo.service
foo.service
   Loaded: error (Reason: No such file or directory)
   Active: active (running) since Mon 2013-07-08 13:50:29 EST; 48s ago
 Main PID: 1642 (node)

所以 systemd 知道它尚未安装,而且它正在运行。是否有一些命令可以用来停止所有不再具有单元文件的正在运行的服务?


我已经考虑过的事情:

  • systemctl isolate <current-target>

    这会产生停止当前目标不需要的其他手动启动的服务的副作用。

  • 使用systemctl disable而不是手动删除文件

    我愿意,但是这个脚本可能从可以访问正在运行的容器的文件系统的主机运行 - 它不能systemd直接调用。

  • 使用systemctl stop foo.service

    这意味着我知道哪些服务已被卸载。我不想弄清楚(或记住),我想要一个可以随时运行的通用命令来停止任何残留服务。

答案1

我向邮件列表询问,Lennart Poettering 回复了以下建议:

http://lists.freedesktop.org/archives/systemd-devel/2013-July/012083.html

此处引用以供后人参考:


因此,处理此问题的正确方法是确保相关软件包包含正确的脚本,这些脚本会在卸载之前终止它们包含的所有单元。当然,我担心总会有像这样的损坏软件包,因此我完全可以理解您的用例。

目前还没有很好的方法来处理这个问题,但你可以这样做:

$ systemctl --all --type=not-found --type=error

这将列出所有加载状态为“错误”或“未找到”的单元(请注意,“未找到”仅在较新的版本中可用,而在较旧的 systemd 版本中只是“错误”的特殊情况。上面的命令行适用于所有版本)。 --type= 开关用于过滤单元类型,但实际上也可用于过滤加载状态。

然后过滤掉第一列:

$ systemctl --no-legend --all --type=not-found --type=error | awk '{ print $1 }'

这将为您提供已引用或启动但未安装单元文件的单元文件列表。然后使用它来停止单元:

$ systemctl stop `systemctl --no-legend -all --type=not-found --type=error | awk '{ print $1}'`

相关内容