--- tags: notes, timer, systemd --- # 使用 systemd timer 取代 crontab - 現代主流的 Linux 系統,預設使用 systemd 做系統管理 - systemd timer 可取代 crontab,較易 debug 和操作,重要的工作推薦花時間改寫 - 避免文章過於複雜,簡化功能描述 - 本文假設用戶有 root 權限 - 本文連結 : https://hackmd.io/@kmo/notes_systemd_timer ## systemd timer 優點 ::: spoiler - 較容易 debug - 當上一時間步 `foo.service` 還處於執行狀態,下一時間步到了也不會重複執行 `foo.service`,可以避免重複執行造成 process 壘加,導致系統異常 - 舉例來說: 每 5 分鐘執行一次 `foo.service`,當 09 點 10 分到了,結果 09 點 05 分的 `foo.service` 還在執行中,`foo.timer` 判斷 `foo.service` 還是處於`activating` 狀態,就不會再啟動 `foo.service` - systemd timer 可精確到秒,以秒執行,而 crontab 較難以實現。比如 30 秒執行一次腳本,使用 systemd timer 可輕易實現 - 可透過 `foo.service` 承接 Linux 的功能,比如限制使用的 CPU 和記憶體等 ::: ## systemd timer 缺點 ::: spoiler - 相對於 crontab,使用 systemd timer 需要撰寫 2 個檔案 - 學習曲線相對高。需要對 Linux 系統較高的熟悉度,才會較好理解,也比較不容易出錯 ::: ## systemd 基本介紹 ::: spoiler - systemd 常見於系統以下 2 位置 ```bash= # 用戶自定義檔案,也是接下來會用到路徑 /etc/systemd/system/* # 通常為系統安裝套件預設放置位置 (ex: deb, rpm...) /usr/lib/systemd/system/* ``` - systemctl 基本指令 ```bash= # 立即執行 or 停止指定的 service systemctl {start,stop} foo.service # 啟用 or 取消開機時會自動執行指定的 service systemctl {enable,disable} foo.service # 重啟指定的 service systemctl restart foo.service # 當有編輯 systemd,記得 reload systemctl daemon-reload ``` - systemctl 操作以上指令,會記錄到作業系統的 syslog,如 CentOS 7 作業系統的 `/var/log/messages` - 當使用 `systemctl` 指令操作時,若沒有加結尾,預設你是指 `.service` 舉例如下,以下是相同指令 ```bash= systemctl status foo systemctl status foo.service ``` - 其他結尾有特定功能。例如本文介紹 `*.timer`,`*.timer` 會去執行和自己同樣名稱的 `*.service`。如 `foo.timer` 時間到會去執行`foo.service` ::: ## systemd timer 範例 - 為最簡單範例,只留下必要設定 ### 情境 - 每 5 分鐘執行一次腳本 `/opt/foo.sh` ### 撰寫 systemd 的檔案 ::: spoiler - 分別撰寫 2 個檔案,`foo.service` 和 `foo.timer` 放底下指定路徑 - service 功能 : 定義執行什麼工作 (what) - timer 功能 : 定義何時執行 (when) - `/etc/systemd/system/foo.service` ```bash= [Service] Type=oneshot ExecStart=/opt/foo.sh [Install] WantedBy=multi-user.target ``` - `/etc/systemd/system/foo.timer` ```bash= [Timer] OnBootSec=5min OnUnitActiveSec=5min AccuracySec=1min [Install] WantedBy=timers.target ``` - 當有編輯 systemd 記得 reload ```bash= systemctl daemon-reload ``` ::: ### systemd 檔案參數說明 ::: spoiler - `/etc/systemd/system/foo.service` ```bash= Type=oneshot #oneshot 是指執行一次 ExecStart=/opt/foo.sh #這邊指定你要執行的腳本路徑,權限要可執行 ``` - `/etc/systemd/system/foo.timer` ```bash= OnBootSec=5min #開機後 5 分鐘執行 OnUnitActiveSec=5min #每 5 分鐘執行一次 AccuracySec=1min #精確到分鐘 ``` ::: ### 測試及啟用 systemd ::: spoiler - 主要腳本是透過 service 執行,先執行一次 `foo.service`,確認能成功執行 ```bash= # start systemctl start foo.service # check status systemctl status foo.service ``` - 執行 `foo.timer`,當設定的每 5 分鐘時間到了,`foo.timer` 會自動執行 `foo.service` ```bash= # start systemctl start foo.timer ``` - 列出 timer 並查看 `foo.timer` 執行的狀態 (很重要的功能) ```bash= systemctl list-timers ``` - 確認符合預期後,啟用讓他開機能自動執行 ```bash= systemctl enable foo.timer ``` ::: ## 後記 ::: spoiler - 由於沒有詳盡到每個參數解釋,網路上也已經有很多不同詳細中文/英文資料說明 systemd,當有不懂推薦可以先 google 關鍵字查看看 :) ::: ## 參考連結 ::: spoiler - [ ubuntu 論壇網友回覆](https://askubuntu.com/a/1083647): 本文參考此網友說明的概念 - [arch linux 的 wiki](https://wiki.archlinux.org/title/systemd): 針對 systemd 說明文件,非常簡潔清楚 - [systemd unit 的官方文件](https://www.freedesktop.org/software/systemd/man/systemd.unit.html) - [systemd timer 的官方文件](https://www.freedesktop.org/software/systemd/man/systemd.timer.html) ::: --- {%hackmd @kmo/widget_license %}
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.