Linux中用systemd来设置定时器是一个相对简单但是功能强大的操作,定时器能增加另外一种启动服务的方式,而使用systemd定时器会更灵活。
假设我们需要创建一个定时器来设置Minetest服务器,让服务器启动一分钟后可以自动运行游戏服务器而非启动服务器后立即执行。因为启动游戏服务器前可能还会需要其他服务,如发送邮件、开启网络等。因此需要其他服务在游戏服务器开启前完全处于启动运行状态:
# minetest.timer
[Unit]
Description=Runs the minetest.service 1 minute after boot up
[Timer]
OnBootSec=1 m
Unit=minetest.service
[Install]
WantedBy=basic.target
以上命令中,Unit跟着描述单元作用的信息,timer包含的是何时启动服务,启动哪些服务。OnBootSec是发送systemd在系统启动后运行服务的指令。包括:OnActiveSec=,告诉 systemd 在定时器启动后多长时间运行服务。其他指令包含:
OnStartupSec=:传达 systemd 在 systemd 进程启动后多长时间运行服务。
OnUnitActiveSec=:传达systemd在上次由定时器激活的服务启动后多长时间运行服务。
OnUnitInactiveSec=:传达systemd在上次由定时器激活的服务停用后多长时间运行服务。
Minetest.Timer中basic.target一般是作为后期引导服务late boot service同步点。这代表可以让minetest.timer单元运行后安装完本地挂载点或交换设备,套接字、定时器、路径单元和其他基本初始化进程后。Target可以当成旧的运行等级,能把服务器置于某些状态,或者是传达服务器到达某个状态后开始运行:
# minetest.service
[Unit]
Description= Minetest server
Documentation= https://wiki.minetest.net/Main_Page
[Service]
Type= simple
User=
ExecStart= /usr/games/minetest --server
ExecStartPost= /home//bin/mtsendmail.sh "Ready to rumble?" "Minetest Starting up"
TimeoutStopSec= 180
ExecStop= /home//bin/mtsendmail.sh "Off to bed. Nightie night!" "Minetest Stopping in 2 minutes"
ExecStop= /bin/sleep 120
ExecStop= /bin/kill -2 $MAINPID
[Install]
WantedBy= multi-user.target
需要把mtsendmail.sh发送email脚本:
#!/bin/bash
# mtsendmail
sleep 20
echo $1 | mutt -F /home/<username>/.muttrc -s "$2" my_minetest@mailing_list.com
sleep 10
修改:
#!/bin/bash
# mtsendmail.sh
echo $1 | mutt -F /home/paul/.muttrc -s "$2" pbrown@mykolab.com
删除Bash中不需要停顿,systemd可实现等待。确保一切正常后禁用minetest.service:
sudo systemctl disable minetest
这样系统启动时不会一同启动,而启用minetest.timer:
sudo systemctl enable minetest.timer
重启服务器,sudo journalctl -u minetest.*会出现minetest.timer 单元执行后大约一分钟,minetest.service 单元开始运行。