skip to content
鰭狀漏斗

systemd timer

/ 閱讀時間 5 分鐘

先前我有介紹過怎麽做出一個 systemd 的服務。接著在這篇文章,我要介紹怎麽寫出一個 timer,讓服務在指定的時間啟動。

Timer 範例

先直接從一個範例看起,這個是 Podman 自動更新的 timer 本體:

podman-auto-update.timer
[Unit]
Description=Podman auto-update timer
[Timer]
OnCalendar=daily
RandomizedDelaySec=900
Persistent=true
[Install]
WantedBy=timers.target
  • OnCalendar= 大概是 timer 最重要的設定,後面會詳細說明。這邊做的設定是每天午夜觸發一次。
  • RandomizedDelaySec= 可以設定在原本的觸發時間加上一個隨機的延遲,避免伺服器超載。
  • Persistent=true 的時候,會在儲存上次觸發的時間到磁碟,如果 timer active 的時候發現超過原先設定該觸發的時間,就會立刻觸發一次。
  • WantedBy=timers.target 是 systemd 文件推薦的設定。

觸發的對象

在上面的範例中並沒有指定這個 timer 觸發的對象,它觸發的對象是誰呢?

就是跟它同名的服務,範例的 podman-auto-update.timer 就是觸發 podman-auto-update.service

此外也可以另外在 [Timer] section 下的 Unit= 指定觸發對象。

文件建議將 timer 跟要觸發的服務設成相同名字,而不是用 Unit= 指定觸發對象。

想觸發指令怎麼辦?

systemd timer 只能觸發 systemd 服務,如果要讓 timer 定期執行指令,需要將指令做成一個 systemd 服務。如果需要範例,可以參考上次介紹的 podman-auto-update.service

OnCalendar=

這個設定是指定要在日曆或時鐘的哪一個時間點觸發。

如果沒有要複雜的設定,可以用這些比較容易懂的特殊設定值:

  • minutely:每分鐘執行一次
  • hourly:每小時執行一次
  • daily:每天執行一次
  • monthly:每月執行一次
  • weekly:每週執行一次
  • yearly:每年執行一次
  • quarterly:每季執行一次
  • semiannually:每半年執行一次

如果要更進階的設定,就要用它的格式,格式長這樣:

星期 年-月-日 時:分:秒

裡面的每個值可以指定:

  • 一個數字
  • 用逗號分隔的多個數字
  • A..B:代表數字 A 到數字 B 的範圍
  • A/B:代表從數字 A 開始每隔數字 B 一次
  • *:代表任意值

如果時間符合設定值的話,timer 就會觸發。

星期不是必須的,如果不指定星期幾的話,可以略過,但不能指定 *

我還省略了一些可用的格式,如果想知道所有可用的格式,可以看文件

因為光這些就不好懂了,所以下面我會舉幾個範例:

範例 1

*-*-* *:*:00

除了秒以外,其他都是 *,代表只要秒數是 0,就會觸發。所以照這個設定,每分鐘 0 秒時會觸發。它跟 minutely 相同。

範例 2

*-*-* 00,06,12,18:00:00

我們有指定小時、分鐘跟秒,分鐘跟秒都是 0,小時則是 00,06,12,18,代表會在 0、6、12、18 時整觸發。

範例 3

*-*-* *:*:00/17

除了 0 秒時會觸發一次外,每隔 17 秒也會觸發一次,其實相當於:

*-*-* *:*:00,17,34,51

範例 2 也可以改寫成:

*-*-* 00/6:00:00

範例 4

2025-02-11 *-*-*

這個範例只有指定日期,卻沒有指定時間,代表會在 2025 年 2 月 11 日的每一秒都會觸發。

範例 5

Tue,Fri 2025-*-* 03,19:10:00

在 2025 年每個星期二和星期五的 3 時 10 分及 19 時 10 分會觸發。

測試看看

我們可以用這個指令測試:

Terminal window
systemd-analyze calendar <SPEC>

不過它只會告訴你下一次會觸發的時間點,無法告訴你全部會觸發的時間點,所以有點沒用。

參考資料