systemd 提供的 timer 功能,可以用來代替 crontab,且其功能更多一些,也可達成類似 anacron 的功能。但設置起來當然也就複雜了一點點,習慣用 crontab 的人應該會強烈的感到麻煩吧 :p
這邊要紀錄的是基本功能,也就是在指定的時間,或是定期執行某個 script。
systemd 的概念,是將你要執行的 script 先設置成 service,然後你應該可以手動執行這個 service,也可以透過 timer 去執行它。也就是說,要將原本 crontab 做的項目改用 systemd,一個項目就會對應到兩個檔案,service 與 timer。
先從 service 開始,現在我們有個 script 需要每分鐘定期執行,這個 script 個工作很簡單,紀錄下自己執行的時間,寫到 logs 資料夾內。
1 2 3 4 5 6 7 |
#!/bin/bash cd $(dirname $0) [ ! -e "logs" ] && mkdir logs time_str=$(date +%Y%m%d_%H%M%S) echo "$time_str" > logs/"$time_str".log |
將這個 script 存放到 /root/bin/log_time.sh 這個位置。接著就可以建立 service 了:
1 2 3 4 5 6 |
[Unit] Description=Run script to log execution time [Service] Type=simple ExecStart=/root/bin/log_time.sh |
Unit 那邊只是給個描述,說明這個的用途。Service 那邊就比較重要了,其中 Type=simple 表示這個 service 是標準行為。若將 Type 設為 oneshot 就只會被執行一次。ExecStart 則是要執行的 script,要加上參數也是直接接在後面就可以了喔。
這個 service 檔案應該要存放在 /etc/systemd/system/logtime.service,然後就可以測試看看是否能夠執行了:
1 2 3 |
# systemctl start logtime.service # ls /root/bin/logs/ 20150625_053841.log |
看起來成功執行嘍,接著就是要讓它定期能夠運作了。我們開啟一個新的 timer 檔案:
1 2 3 4 5 6 7 8 9 |
[Unit] Description=Run logtime every minutes [Timer] OnCalendar=*-*-* *:*:00 Unit=logtime.service [Install] WantedBy=multi-user.target |
Timer 那邊是指定要執行的時間與 service。時間的格式很簡單,由左到右分別是 年-月-日 時:分:秒。以 * 代表的話就表示任意。上面的例子裡我們讓 timer 在每分鐘 00 秒時執行。最底下的 install 也很重要,它決定這個 timer 在什麼情況下會啟動。WantedBy=multi-user.target 意思是在多人模式下會自動啟動這個 timer。我想大部分應該都是用這個才對。
最後我們一樣將這個 timer 檔案存放到 /etc/systemd/system/logtime.timer 就可以了。設置到這個階段,還需要將這個 timer 啟用。其中包括了開機時自動啟用,以及現在不重開機的狀況下開始執行。
用下列命令來開機自動啟用:
1 2 |
# systemctl enable logtime.timer Created symlink from /etc/systemd/system/multi-user.target.wants/logtime.timer to /etc/systemd/system/logtime.timer. |
用這個命令來檢查是否已啟用:
1 2 |
# systemctl is-enabled logtime.timer enabled |
啟用後的 timer 會在開機後自動執行,但是若不想重開機就開始的話,得手動去執行它:
1 |
# systemctl start logtime.timer |
然後這樣檢查是否有在執行:
1 2 3 |
# systemctl list-timers NEXT LEFT LAST PASSED UNIT ACTIVATES Thu 2015-06-25 05:59:00 UTC 17s left Thu 2015-06-25 05:58:06 UTC 36s ago logtime.timer logtime.service |
去檢查一下 logs 資料夾,果然每分鐘都會出現新的 log 了:
1 2 |
# ls /root/bin/logs/ 20150625_053841.log 20150625_055806.log 20150625_055902.log 20150625_060015.log 20150625_060115.log |
同場加映
上面講的是系統層級的設定方法,那麼有沒有使用者個人的 timer 與 service 可以用呢?
有的。首先要說明的是,systemd 只會在使用者有登入的狀態才會幫它執行 timer。若是要讓使用者登出後還能正常運作,需要做這個設置:
1 |
$ loginctl enable-linger username |
你可以這樣檢查 linger 是否啟用:
1 2 3 4 |
$ loginctl show-user username ...... ...... Linger=yes |
接著,使用者的 service 與 timer 檔應該要放在 ~/.config/systemd/user 裡面。啟用 timer 的方式基本上相同,但是要多加一個參數 –user:
1 2 3 4 5 6 |
$ systemctl --user enable logtime.timer Created symlink from /home/username/.config/systemd/user/multi-user.target.wants/logtime.timer to /home/username/.config/systemd/user/logtime.timer. $ systemctl --user start logtime.timer $ systemctl --user list-timers NEXT LEFT LAST PASSED UNIT ACTIVATES Thu 2015-06-25 06:20:00 UTC 34s left n/a n/a logtime.timer logtime.service |
參考資料
- https://wiki.archlinux.org/index.php/Systemd
- https://wiki.archlinux.org/index.php/Systemd/Timers
- https://wiki.archlinux.org/index.php/Systemd/User
- https://sevenbyte.org/2014/11/15/cron-jobs-with-systemd-timer/
- http://jason.the-graham.com/2013/03/06/how-to-use-systemd-timers/
- http://www.freedesktop.org/software/systemd/man/systemd.unit.html
自動引用通知: 定時自動重啟服務 – Thinking more…