如何在另一个单元运行时停止一个单元

如何在另一个单元运行时停止一个单元

我目前正在尝试使用设置自动备份博格。为此,我编写了一个 oneshot systemd 用户服务(称为 borgbackup.service),我计划通过计时器启动它。

Borg 还可以将备份存储库挂载为虚拟文件系统,我希望始终挂载我的备份。我为它编写了另一个用户服务,我称之为 borgmount.service。但是,在安装存储库时无法创建备份。

我当前对此问题的解决方案包括 borgbackup.service 中的这些行,用于在备份之前和之后停止和重新启动安装服务。

ExecStartPre=/usr/bin/systemctl --user stop borgmount.service
ExitStart=/bin/sh -c "borg create ::$(date) --exclude-caches --keep-tag-files"
ExecStopPost=/usr/bin/systemctl --user start borgmount.service

这看起来非常丑陋,并且没有考虑备份启动时 borgmount.service 单元所处的状态(可能已停止并禁用)。

有一个更好的方法吗?

答案1

这不是一个完美的解决方案,但ExecStartPre您可以使用Conflicts.

冲突=

以空格分隔的单位名称列表。配置负面需求依赖性。如果一个单元在另一个单元上有 Conflicts= 设置,则启动前者将停止后者,反之亦然。请注意,此设置与 After= 和 Before= 排序依赖关系无关且正交。

您可以将其与ExecStopPost检查是否启用冲突的命令结合起来:

ExecStopPost=/usr/bin/systemctl is-enabled borgmount.service && /usr/bin/systemctl --user start borgmount.service

如果您不熟悉&&操作符,如果第一个命令成功,则将执行第二个命令。systemctl is-enabled当该单元启用时返回 0。

仍然没有涵盖服务启用和停止的用例,但您可能仍然可以处理更复杂ExecStopPost甚至确定的状态ExecStartPre。可惜systemd没有Interupts指令或类似指令,只能在另一个单元运行时停止该单元。


除了 an 之外,ExecStartPost您还可以指定Conflicts=inborgmount.service和 而不是只运行,systemctl start borgbackup.service您可以 run systemctl start borgbackup.service borgmount.service,但这需要记住同时运行两者。


另一种选择(可能是最干净的)是Conflicts在这两种服务中使用,并创建一个包含这两种服务的新备份目标。

borgbackup.service需要:

Before=borgmount.service确保它首先运行

WantedBy=${NEW_TARGET}以确保运行新目标会导致其运行。

borgmount.service需要:

WantedBy=${NEW_TARGET},您可以WantedBy在一个单元中指定多个指令。

然后您可以使用 触发备份systemctl start ${NEW_TARGET}

此方法的好处是,如果borgmount.service未启用,它将不会在 中运行${NEW_TARGET},如果您想在不运行的情况下触发备份,您可以单独borgmount.service调用。borgbackup.service

相关内容