Linux 定时器
在 Linux 系统中,定时器一般是使用
cron
这个系统工具来实现的。 或者,在 systemd 中也可以使用Timer
进行定时控制。
Cron
在linux下,可以使用crontab -e
来编辑修改定时任务(重点在最后一行)
# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command
每项任务前五项为时间配置,第六项为待执行的命令。
定时任务时间配置说明
符号 | 范围 | 含义 | 描述 |
---|---|---|---|
m | 0~59 | minute | 每小时的第几分钟执行 |
h | 0~23 | hour | 每天的第几个小时执行 |
dom | 1~31 | day of month | 每月的第几天执行 |
mon | 1~12 | month | 每年的第几个月执行 |
dow | 0~6 | day of week | 每周的第几天执行, 0为星期天 |
其中月份mon也可以使用jan~dec
,而周dow也可以使用sun~sat
。即使用英文单词前三个字母,大小写无关。
时间配置每一项设置
* 表示任意值,即每小时或者每天,每月
/ 表示每隔*时
, 表示多项时间触发
示例:
*/2 * * * * /usr/local/bin/play # 每隔2分钟(整点开始计算)执行play程序
30 11 * * * /bin/echo "tick tock" # 每天11点30分输出tick tock
* * * * 1,3 /usr/local/bin/backup # 每周一、周三进行备份操作
如果觉得上面有好几项配置太麻烦,可以使用下面简单时间配置
@reboot 执行一次,系统重启后执行
@yearly 每年执行一次(0 0 1 1 *)
@annually 与@yearly相同
@monthly 每月执行一次(0 0 1 * *)
@weekly 每周执行一次(0 0 * * 0)
@daily 每天执行一次(0 0 * * *)
@midnight 与@daily相同,每晚0点执行一次
@hourly 每小时执行一次(0 * * * *)
示例
@reboot /bin/echo "Startup" # 在重启后打印Startup
@hourly /usr/local/bin/httpcheck # 每小时进行httpcheck检查
最终crontab -e
文件内容始下:
# Edit this file to introduce tasks to be run by cron.
#
# ...省略了中间注释内容
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command
*/2 * * * * /usr/local/bin/play
30 11 * * * /bin/echo "tick tock"
* * * * 1,3 /usr/local/bin/backup
@reboot /bin/echo "Startup"
@hourly /usr/local/bin/httpcheck
重启cron
服务,使定时任务生效
# Systemd
systemctl restart cron.service
# Old Debian/Ubuntu
service cron restart
# Old CentOS/RHEL
service crond restart
Timer
在systemd中是以定时器(timer)去控制服务(service)来实现定时功能。
一个典型的定时器文件以.timer
为后缀名。其内容大致如下:
[Unit]
Description=Run weekly and on boot
[Timer]
# 在启动15分钟后执行
OnBootSec=15min
# 下一次执行是一周后
OnUnitActiveSec=1w
# 此处使用foo.service作为定时器执行的服务,默认使用与timer同名的服务
Unit=foo.service
[Install]
WantedBy=timers.target
文件中Timer块其它选项包括:
选项 | 示例值 | 说明 |
---|---|---|
OnActiveSec | 30s | 相对于该单元自身被启动的时间点 |
OnBootSec | 15m | 相对于机器被启动的时间点 |
OnStartupSec | 2h | 相对于systemd被首次启动的时间点 |
OnUnitActiveSec | 1w | 相对于匹配单元最后一次被启动的时间点 |
OnUnitInactiveSec | 2d | 相对于匹配单元最后一次被停止的时间点 |
OnCalendar | Mon,Tue --01..04 12:00:00 | 日历定时事件表达式 |
AccuracySec | 5m | 设置定时器的触发精度 |
RandomizedDelaySec | 10m | 将此单元的定时器随机延迟一小段时间 |
Unit | foo.service | 该定时器启动的单元(默认是与timer同名的service) |
Persistent | yes, no | 上次触发时间是否永久保存在磁盘上(仅适用于OnCalendar定义的日历定时器) |
WakeSystem | yes, no | 是否唤醒正在休眠的系统并阻止系统进入休眠状态 |
RemainAfterElapse | yes, no | 是否保持已过期定时器单元的已加载(loaded)状态 |
关于systemd中service,请参见前面文章《使用Systemd管理应用》
Systemd Timer 示例