如何在Linux中使用systemd設置定時器
背景
定時器在Linux中被廣泛使用。它用於在特定時間或間隔內安排任務運行。例如,您可以使用定時器在每天、每週或每月的特定時間運行備份腳本。
一些用途:
- 安排自動備份:例如,您可以設置一個定時器,在每天的特定時間運行備份數據庫。
- 監控系統性能:安排定期檢查CPU使用率、內存使用率、磁盤空間和其他系統指標。這有助於管理員在問題變得嚴重之前識別和解決性能問題。
- 定期運行腳本:Linux定時器可用於定期運行腳本。這對於清理臨時文件、運行系統維護腳本等任務非常有幫助。
舊版本的Linux使用cron守護程序安排任務。然而,cron守護程序不再推薦用於新安裝。相反,您應該使用systemd定時器。
列出現有的定時器
使用以下命令列出所有現有的定時器:
systemctl list-timers您將看到一個定時器列表,包括定時器的名稱、下一次觸發時間和上一次觸發時間。
NEXT LEFT LAST PASSED UNIT ACTIVATES
Wed 2023-03-29 10:06:35 CST 4min 49s left n/a n/a ua-timer.timer ua-timer.service
Wed 2023-03-29 10:14:03 CST 12min left n/a n/a systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service
Wed 2023-03-29 17:35:56 CST 7h left n/a n/a motd-news.timer motd-news.service
Thu 2023-03-30 00:00:00 CST 13h left n/a n/a dpkg-db-backup.timer dpkg-db-backup.service
Thu 2023-03-30 00:00:00 CST 13h left n/a n/a logrotate.timer logrotate.service
Thu 2023-03-30 03:27:59 CST 17h left n/a n/a apt-daily.timer apt-daily.service
Thu 2023-03-30 06:58:06 CST 20h left n/a n/a apt-daily-upgrade.timer apt-daily-upgrade.service
Sun 2023-04-02 03:10:16 CST 3 days left n/a n/a e2scrub_all.timer e2scrub_all.service在 Linux systemd 中設置定時器
要設置定時器,您需要使用 root 用戶或具有 sudo 權限的用戶。
要在 Linux systemd 中設置定時器並將輸出記錄到文件中,請按照以下步驟操作:
首先,在 /etc/systemd/system 目錄中創建一個新的定時器單元文件。您可以將其命名爲任何名稱,但必須具有 .timer 擴展名。例如,創建一個名爲 helloworld.timer 的文件。
在定時器單元文件中,添加以下行:
[Unit]
Description=Hello World Timer
[Timer]
OnCalendar=*:0/10
Unit=helloworld.service
[Install]
WantedBy=timers.target.timer 文件是一個 systemd 單元文件,用於定義定時器。它包含一個 [Unit] 部分,提供定時器的描述,一個 [Timer] 部分,定義定時器何時觸發以及要運行的服務,以及一個 [Install] 部分,指定定時器應安裝在何處。
這告訴系統每 10 分鐘運行一次 helloworld.service 單元,並使用 OnCalendar 將定時器設置爲在任何小時的第 10 分鐘(*) 觸發。
注意:
OnCalendar使用靈活的語法來定義定時器何時觸發。在此示例中,*:0/10表示“每 10 分鐘一次”。您可以使用其他值來指定不同的間隔。更多信息請參見附錄。
然後,在同一目錄中創建一個新的服務單元文件。同樣,您可以將其命名爲任何名稱,但必須具有 .service 擴展名。例如,創建一個名爲 helloworld.service 的文件。
在服務單元文件中添加以下行:
[Unit]
Description=Hello World Service
[Service]
Type=oneshot
ExecStart=/bin/echo "Hello World"
[Install]
WantedBy=multi-user.target.service 文件是一個 systemd 單元文件,用於定義服務。[Unit] 和 [Install] 部分與 .timer 文件類似。[Service] 部分定義了服務的執行方式。
這告訴系統在定時器觸發時運行 /bin/echo "Hello World" 命令。
重新加載 systemd 守護程序以加載新的單元文件:
sudo systemctl daemon-reload啓用並啓動定時器:
sudo systemctl enable helloworld.timer
sudo systemctl start helloworld.timer現在,系統將每隔 10 分鐘打印 "Hello World" 並將輸出記錄到文件中。我們可以再次檢查定時器列表以查看定時器是否正在運行:
systemctl list-timersNEXT LEFT LAST PASSED UNIT ACTIVATES
Wed 2023-03-29 10:10:00 CST 1min 46s left n/a n/a helloworld.timer helloworld.service
Wed 2023-03-29 10:14:03 CST 5min left n/a n/a systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service
Wed 2023-03-29 16:14:38 CST 6h left Wed 2023-03-29 10:06:43 CST 1min 29s ago ua-timer.timer ua-timer.service
Wed 2023-03-29 17:18:24 CST 7h left n/a n/a motd-news.timer motd-news.service
Thu 2023-03-30 00:00:00 CST 13h left n/a n/a dpkg-db-backup.timer dpkg-db-backup.service
Thu 2023-03-30 00:00:00 CST 13h left n/a n/a logrotate.timer logrotate.service
Thu 2023-03-30 05:50:50 CST 19h left n/a n/a apt-daily.timer apt-daily.service
Thu 2023-03-30 06:41:07 CST 20h left n/a n/a apt-daily-upgrade.timer apt-daily-upgrade.service
Sun 2023-04-02 03:10:39 CST 3 days left n/a n/a e2scrub_all.timer e2scrub_all.service如您所見,helloworld.timer 正在運行,下一次觸發時間爲 1 分鐘 46 秒後。等待幾分鐘並檢查日誌文件:
journalctl -u helloworld.service您應該會看到 echo 命令的輸出:
Mar 29 10:10:02 ubuntu systemd[1]: Starting Hello World Service...
Mar 29 10:10:02 ubuntu echo[7942]: Hello World
Mar 29 10:10:02 ubuntu systemd[1]: helloworld.service: Deactivated successfully.
Mar 29 10:10:02 ubuntu systemd[1]: Finished Hello World Service.如果您想將輸出重定向到文件中,可以更改服務單元文件中的 ExecStart 行:
ExecStart=/bin/sh -c '/bin/echo "Hello World" >> /tmp/helloworld.log'附錄
OnCalendar
OnCalendar是定時器單元文件中[Timer]部分的一個選項,用於指定定時器何時觸發。OnCalendar的語法如下:
OnCalendar=日曆表達式可以是簡單或複雜的表達式,用於指定任務的計劃。完整的表達式如下:
星期幾 年-月-日 時:分:秒- 星期幾:
Mon,Tue,Wed,Thu,Fri,Sat,Sun - 年/月/日:使用數字
- 時/分/秒:使用數字
每個部分都可以是範圍、列表或間隔,或者使用*匹配任何值。例如:
Mon..Fri:星期一到星期五Mon,Fri:星期一和星期五8..18/2:上午8:00到下午6:00,每2小時*-*-1:每個月的第一天
每個部分都可以省略。例如:
- 要每小時運行一次任務,請使用
OnCalendar=*:0 - 要每天下午3:30運行一次任務,請使用
OnCalendar=15:30 - 要每個星期一上午9:00運行一次任務,請使用
OnCalendar=Mon 9:00 - 要每15分鐘運行一次任務,請使用
OnCalendar=*:0/15 - 要在工作日的上午8:00運行一次任務,請使用
OnCalendar=Mon..Fri 8:00
除了這些基本表達式外,您還可以使用包含範圍、列表和間隔的更復雜的表達式。以下是一些示例:
- 要在上午8:00到下午6:00之間每2小時運行一次任務,請使用
OnCalendar=8..18/2:0 - 要在每個月的第15天上午10:00運行任務,請使用
OnCalendar=*-*-15 10:00
您還可以使用特殊關鍵字 minutely、hourly、daily、weekly、monthly 和 yearly 來指定常見的計劃。
您始終可以使用 systemd-analyze 命令驗證您的 OnCalendar 表達式:
systemd-analyze calendar "Mon..Fri 8:00"輸出將顯示錶達式的規範化形式和下一個過期時間:
Original form: Mon..Fri 8:00
Normalized form: Mon..Fri *-*-* 08:00:00
Next elapse: Thu 2023-03-30 08:00:00 CST
(in UTC): Thu 2023-03-30 00:00:00 UTC
From now: 18h left總的來說,OnCalendar 選項提供了一種靈活而強大的方式來使用 systemd 定時器在 Linux 中安排任務。通過理解語法並使用適當的日曆表達式,您可以自動化您的系統,節省時間和精力。
