仅在日历事件上使用 systemd 定时器

Only use systemd timer oncalendar events

我正在尝试在 :0/5:00(每 5 分钟)获取到 运行 的服务。此过程可能需要 5 分钟或多于或少于 5 分钟。如果它超过了 5 分钟标记,则什么也不做,并在下一个 5 分钟块开始下一个。

当该过程花费的时间少于 5 分钟时,这一切都正常工作,但如果该过程花费的时间超过 5 分钟,它会立即重新启动服务。

根据我的阅读,默认行为是在服务时间溢出时跳过下一次执行(参见 https://unix.stackexchange.com/questions/203254/does-systemd-timer-unit-skip-the-next-run-if-the-process-hasnt-finished-yet). However, I also see a question which seems to indicate that the service will start as soon as the previous execution completes (see https://unix.stackexchange.com/questions/487562/how-to-make-systemd-timer-run-exactly-every-10-minutes-with-a-task-that-lasts-s),这符合我的经验。

(出于测试目的,我使用 :0/1:0 这样我就不必每次都等待 5 分钟)

我的计时器:

[Unit]
Description=Start service on timed schedule.
After=network-online.target
Wants=network-online.target

[Timer]
OnCalendar=*:0/1:0
AccuracySec=1us

[Install]
WantedBy=timers.target

我的服务:

[Unit]
Description=Do a thing
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
ExecStart=/bin/bash /usr/local/bin/my-script.sh

我的脚本:

#!/bin/bash

PROG="/usr/local/bin/fake-third-party.sh"

exec $PROG &>> /tmp/timer_testing.out

伪造的第三方脚本:

#!/bin/bash

echo "`date` I sleep now"

sleep 76

echo "`date` No more sleep"

所以现在,当 76 结束时,它会立即开始下一个。

Thu Jun 25 13:01:00 UTC 2020 I sleep now
Thu Jun 25 13:02:16 UTC 2020 No more sleep
Thu Jun 25 13:02:16 UTC 2020 I sleep now
Thu Jun 25 13:03:32 UTC 2020 No more sleep
Thu Jun 25 13:03:32 UTC 2020 I sleep now

当我要寻找的是:

13:01:00 -> sleep
13:02:16 -> wake
13:03:00 -> sleep
13:04:16 -> wake
13:05:00 -> sleep

目前正在使用的一种可能(又名骇人听闻的)解决方案如下:

更改 my-script.sh 使其位于前面:

minutes=$(date +"%-M" | tail -c 2)
seconds=$(date +"%S")
if [[ "$seconds" != "00" || ! ( "$minutes" == "0" || "$minutes" == "5" ) ]]; then
then
  exit 0
fi

这确实触发了 my-script.sh,但脚本从未调用 exec third-party-script,因此它满足了要求。

不过我想用 'proper' 的方式来做,如果有的话。