Systemd 定時器教程


Systemd 定時器教程

 

Systemd 作為 Linux 的系統啟動器,功能強大。

本文通過一個簡單例子,介紹 Systemd 如何設置定時任務。這不僅實用,而且可以作為 Systemd 的上手教程。

一、定時任務

所謂定時任務,就是未來的某個或多個時點,預定要執行的任務,比如每五分鍾收一次郵件、每天半夜兩點分析一下日志等等。

Linux 系統通常都使用 cron 設置定時任務,但是 Systemd 也有這個功能,而且優點顯著。

  • 自動生成日志,配合 Systemd 的日志工具,很方便除錯
  • 可以設置內存和 CPU 的使用額度,比如最多使用50%的 CPU
  • 任務可以拆分,依賴其他 Systemd 單元,完成非常復雜的任務

下面,我就來演示一個 Systemd 定時任務:每小時發送一封電子郵件。

二、郵件腳本

先寫一個發郵件的腳本mail.sh


#!/usr/bin/env bash echo "This is the body" | /usr/bin/mail -s "Subject" .com 

上面代碼的someone@example.com,請替換成你的郵箱地址。

然后,執行這個腳本。


$ bash mail.sh 

執行后,你應該就會收到一封郵件,標題為Subject

如果你的 Linux 系統不能發郵件,建議安裝 ssmtp 或者 msmtp。另外,mail命令的用法,可以參考這里

三、Systemd 單元

學習 Systemd 的第一步,就是搞懂"單元"(unit)是什么。

簡單說,單元就是 Systemd 的最小功能單位,是單個進程的描述。一個個小的單元互相調用和依賴,組成一個龐大的任務管理系統,這就是 Systemd 的基本思想。

由於 Systemd 要做的事情太多,導致單元有很多不同的種類,大概一共有12種。舉例來說,Service 單元負責后台服務,Timer 單元負責定時器,Slice 單元負責資源的分配。

每個單元都有一個單元描述文件,它們分散在三個目錄。

  • /lib/systemd/system:系統默認的單元文件
  • /etc/systemd/system:用戶安裝的軟件的單元文件
  • /usr/lib/systemd/system:用戶自己定義的單元文件

下面的命令可以查看所有的單元文件。


# 查看所有單元 $ systemctl list-unit-files # 查看所有 Service 單元 $ systemctl list-unit-files --type service # 查看所有 Timer 單元 $ systemctl list-unit-files --type timer 

四、單元的管理命令

下面是常用的單元管理命令。


# 啟動單元 $ systemctl start [UnitName] # 關閉單元 $ systemctl stop [UnitName] # 重啟單元 $ systemctl restart [UnitName] # 殺死單元進程 $ systemctl kill [UnitName] # 查看單元狀態 $ systemctl status [UnitName] # 開機自動執行該單元 $ systemctl enable [UnitName] # 關閉開機自動執行 $ systemctl disable [UnitName] 

五、Service 單元

前面說過,Service 單元就是所要執行的任務,比如發送郵件就是一種 Service。

新建 Service 非常簡單,就是在/usr/lib/systemd/system目錄里面新建一個文件,比如mytimer.service文件,你可以寫入下面的內容。


[Unit] Description=MyTimer [Service] ExecStart=/bin/bash /path/to/mail.sh 

可以看到,這個 Service 單元文件分成兩個部分。

[Unit]部分介紹本單元的基本信息(即元數據),Description字段給出這個單元的簡單介紹(名字叫做MyTimer)。

[Service]部分用來定制行為,Systemd 提供許多字段。

  • ExecStartsystemctl start所要執行的命令
  • ExecStopsystemctl stop所要執行的命令
  • ExecReloadsystemctl reload所要執行的命令
  • ExecStartPreExecStart之前自動執行的命令
  • ExecStartPostExecStart之后自動執行的命令
  • ExecStopPostExecStop之后自動執行的命令

注意,定義的時候,所有路徑都要寫成絕對路徑,比如bash要寫成/bin/bash,否則 Systemd 會找不到。

現在,啟動這個 Service。


$ sudo systemctl start mytimer.service 

如果一切正常,你應該就會收到一封郵件。

六、Timer 單元

Service 單元只是定義了如何執行任務,要定時執行這個 Service,還必須定義 Timer 單元。

/usr/lib/systemd/system目錄里面,新建一個mytimer.timer文件,寫入下面的內容。


[Unit] Description=Runs mytimer every hour [Timer] OnUnitActiveSec=1h Unit=mytimer.service [Install] WantedBy=multi-user.target 

這個 Timer 單元文件分成幾個部分。

[Unit]部分定義元數據。

[Timer]部分定制定時器。Systemd 提供以下一些字段。

  • OnActiveSec:定時器生效后,多少時間開始執行任務
  • OnBootSec:系統啟動后,多少時間開始執行任務
  • OnStartupSec:Systemd 進程啟動后,多少時間開始執行任務
  • OnUnitActiveSec:該單元上次執行后,等多少時間再次執行
  • OnUnitInactiveSec: 定時器上次關閉后多少時間,再次執行
  • OnCalendar:基於絕對時間,而不是相對時間執行
  • AccuracySec:如果因為各種原因,任務必須推遲執行,推遲的最大秒數,默認是60秒
  • Unit:真正要執行的任務,默認是同名的帶有.service后綴的單元
  • Persistent:如果設置了該字段,即使定時器到時沒有啟動,也會自動執行相應的單元
  • WakeSystem:如果系統休眠,是否自動喚醒系統

上面的腳本里面,OnUnitActiveSec=1h表示一小時執行一次任務。其他的寫法還有OnUnitActiveSec=*-*-* 02:00:00表示每天凌晨兩點執行,OnUnitActiveSec=Mon *-*-* 02:00:00表示每周一凌晨兩點執行,具體請參考官方文檔

七、[Install] 和 target

mytimer.timer文件里面,還有一個[Install]部分,定義開機自啟動(systemctl enable)和關閉開機自啟動(systemctl disable)這個單元時,所要執行的命令。

上面腳本中,[Install]部分只寫了一個字段,即WantedBy=multi-user.target。它的意思是,如果執行了systemctl enable mytimer.timer(只要開機,定時器自動生效),那么該定時器歸屬於multi-user.target

所謂 Target 指的是一組相關進程,有點像 init 進程模式下面的啟動級別。啟動某個Target 的時候,屬於這個 Target 的所有進程都會全部啟動。

multi-user.target是一個最常用的 Target,意為多用戶模式。也就是說,當系統以多用戶模式啟動時,就會一起啟動mytimer.timer。它背后的操作其實很簡單,執行systemctl enable mytimer.timer命令時,就會在multi-user.target.wants目錄里面創建一個符號鏈接,指向mytimer.timer

八、定時器的相關命令

下面,啟動剛剛新建的這個定時器。


$ sudo systemctl start mytimer.timer 

你應該立刻就會收到郵件,然后每個小時都會收到同樣郵件。

查看這個定時器的狀態。


$ systemctl status mytimer.timer 

查看所有正在運行的定時器。


$ systemctl list-timers 

關閉這個定時器。


$ sudo systemctl stop myscript.timer 

下次開機,自動運行這個定時器。


$ sudo systemctl enable myscript.timer 

關閉定時器的開機自啟動。


$ sudo systemctl disable myscript.timer 

九、日志相關命令

如果發生問題,就需要查看日志。Systemd 的日志功能很強,提供統一的命令。


# 查看整個日志 $ sudo journalctl # 查看 mytimer.timer 的日志 $ sudo journalctl -u mytimer.timer # 查看 mytimer.timer 和 mytimer.service 的日志 $ sudo journalctl -u mytimer # 從結尾開始查看最新日志 $ sudo journalctl -f # 從結尾開始查看 mytimer.timer 的日志 $ journalctl -f -u timer.timer 

十、參考鏈接

(完)

http://www.ruanyifeng.com/blog/2018/03/systemd-timer.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM