systemd 计时器:仅在特定时间范围内启用服务

systemd 计时器:仅在特定时间范围内启用服务

假设我希望一个程序在台式机上的 12:00 到 13:00 之间处于活动状态(即不能保证 PC 在任一时间都处于打开状态)。我假设我可以为此使用 systemd 单位。

A使用计时器启动服务并计算断电时间很简单:

A.定时器

[Timer]
Unit=A
OnCalendar=*-*-* 12:00:00
Persistent=true

A可以通过冲突的服务来停止,如下所示之前建议的

A.服务(有冲突):

#add conflict to A.service
[Unit]
Description=This is A.service
Conflicts=killA.service
#make sure killA considers A to be active
RemainAfterExit=yes

杀死A服务

 [Unit]
 Description=kills A
 [Service]
 Type=oneshot
 ExecStart=/bin/true
 #kill only if A is running:
 Requires=A.service

终止定时器

[Timer]
Unit=killA
OnCalendar=*-*-* 13:00:00
Persistent=true

现在有几种可能的情况:

  • 11点-14点通电:按预期启动和停止
  • 从 11 点到 12 点 30 分通电:按预期启动但从未停止 -> 下次通电时会发生什么?

    • 12:45:A会开始吗? (最后一次启动时间不到 24 小时前)
    • 14 小时:killA 不应运行,因为 A 不应处于活动状态
    • 第二天12点15分? (上次启动时间不到 24 小时,但 KillA 启动被错过)
    • 第二天12点45分? (上次启动>24小时前,但killA<24小时前。会被killA停止吗?)
  • 12:30 至 14h 通电:按预期启动和停止(由于 A.timer 的持久性)

  • 14小时通电:A因持久而启动。由于依赖性,killA会立即停用它吗?从一开始就可以避免开始A吗?

简而言之:

如何使用 systemd 计时器来确保服务在给定时间间隔内处于活动状态,并在时间间隔之外处于非活动状态,与关闭/启动无关?


实践用例示例:ssh仅在工作时间允许访问。

PS:也许我还不太了解 systemd 计时器?

答案1

我有同样的要求。

我可以确认两个计时器在启动时赶上会导致竞争条件,并产生随机结果。

那么系统重启的场景呢?不止一次12 到 13 之间。Persistent在这种情况下可能没有任何帮助。

我的结论(但我希望被证明是错误的)是 systemd 根本不适合这个用例。

我的解决方法是使用上面的配置,不带标志Persistent。然后我创建一个新idle服务,专门用于处理启动后的状态。该服务将当前时间与当前目标服务状态进行比较,如果不匹配则启动/停止服务。请注意,启动/停止时间需要在计时器和“启动管理器”服务脚本中重复,这并不理想。

这是我发现确保我的服务在选定时间段内运行的唯一可靠方法,无论多次重新启动如何。

相关内容