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

Phi*_*ßen 5 systemd systemd-timer

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

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

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/bin/true
ExecStop=<some command to run at system shutdown>
Run Code Online (Sandbox Code Playgroud)

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

  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
Run Code Online (Sandbox Code Playgroud)

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

Mar*_*erg 0

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

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

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

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