先前我有介紹過怎麽做出一個 systemd 的服務。接著在這篇文章,我要介紹怎麽寫出一個 timer,讓服務在指定的時間啟動。
Timer 範例
先直接從一個範例看起,這個是 Podman 自動更新的 timer 本體:
[Unit]Description=Podman auto-update timer
[Timer]OnCalendar=dailyRandomizedDelaySec=900Persistent=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 分會觸發。
測試看看
我們可以用這個指令測試:
systemd-analyze calendar <SPEC>
不過它只會告訴你下一次會觸發的時間點,無法告訴你全部會觸發的時間點,所以有點沒用。