systemd:如何定期运行作业并在系统关闭时运行一次作业?

systemd:如何定期运行作业并在系统关闭时运行一次作业?

我想定期运行一个作业(例如,每 5 分钟),最后在系统关闭时运行一次。

Systemd 支持计时器,可用于定期运行作业。它还支持使用ExecStop这样的钩子在系统关闭时运行作业:

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/bin/true
ExecStop=<some command to run at system shutdown>

但我很难将这两种方法结合起来。我能想到的唯一选择是编写两个独立的服务:

  1. 由定时器任务触发的一项服务
  2. 另一个使用该ExecStop技巧在系统关闭时执行的服务

我认为它应该有效,但这种方法有两个问题:

  1. 关于安全设置有很多代码重复
  2. systemd 无法防止并行运行作业。例如,如果在周期性作业刚刚执行时触发关闭,则两个作业将并行运行。

问题:

  • 定期运行作业并在系统关闭时运行一次作业的最佳方法是什么?
  • 是否可以避免有两个(大部分是重复的)服务文件?

为了了解代码重复的含义,以下是我在运行作业时使用的一些安全设置:

User=foo
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectControlGroups=yes
NoNewPrivileges=yes
PrivateDevices=yes
PrivateUsers=yes
CapabilityBoundingSet=
AmbientCapabilities=
SystemCallFilter=~@clock @module @mount @obsolete @raw-io ptrace
ReadOnlyPaths=-/some/path

在我草拟的方法中,我需要复制此代码(每个服务一份)。

答案1

您可以通过创建两个目录来解决重复问题:foo-at-shutdown.service.d和 'foo-periodic.service.d`。

在一个文件夹中创建一个名为foo-shared.conf.
使用符号链接将其添加到第二个文件夹。

这些是“插入”单元,将被拉入主配置文件中。man systemd.unit如果您在那里搜索“drop-in”,它们会有更多记录。

我认为拥有两个服务文件、一个计时器文件和共享的插入单元文件是一种合理的方法。

相关内容