分析
Linux上的守护进程cron能够根据配置好的crontab定时地执行某一个动作,现在用上systemd了想要找一个替代品,于是找到了timer,timer和其他的配置单元结构差不多,只是有一个[Timer]段,在这里可以定义它的行为。基本的写法是Name=Value。
作为一个timer必须要有
[Install] WantedBy=timers.target
[Unit] Description=Value
这个字段允许添加对配置单元的描述
[Timer] Unit=Value
用于指定该timer触发时要启动的配置单元,如果不写的话,example.timer触发时会执行同名的example.service。
[Timer] 绝对触发时间
OnCalendar=Value可以指定在系统时钟的某一特定时刻触发timer。懒的话可以直接使用hourly,monthly这样的词语,也可以输入DAY YYYY-MM-DD HH:MM:SS。比如hourly与*:00:00等价,Wed *:00:00就是每个星期三隔一个小时触发一次。
[Timer] 相对触发时间
OnBootSec=Value可以指定在系统启动后的一段时间触发timer。OnUnitActiveSec=Value可以指定在timer被触发后的一定时间再次触发timer。这里的Value可以使用h, w ,s来指代hour, week, second。
[Service] Type=Value
由于timer需要配合service并且在触发后会启动一个service,并且这个service必须是单次执行完后就退出,因此在这里没有选择,只能是Type=oneshot
[Service] ExecStart=Command
在这里指定service启动时要执行的指令,有一堆指令的话可以塞在一个脚本里让service执行,也就是每次timer触发要做的事情。
场景
家中的桌面机开放了ssh以便我在桌面机和Surface之间传送文件,为了避免记IP地址的麻烦,我把我的一个域名指向了家里的IP地址,然而中国电信经常喜欢换我的IP,以至于连不上。
需求
让家里的桌面机A能够定时的向一台IP不变的服务器B传送自己的IP地址,这样就可以在服务器B上看到最新的IP地址了。
前置条件
- Archlinux Desktop
changing.example.com - Debian Server
persistent.example.com - 已经配置了无密码密钥对
id_rsa的用户john - 外部设备 Surface
配置文件
以下是send-ip-to-vps.timer,主要的timer配置单元,每个整点触发一次
[Unit] Description=Send public IP to vps [Timer] OnCalendar=hourly [Install] WantedBy=timers.target
以下是send-ip-to-vps.service,对应触发的service配置单元
[Unit] Description=Send public IP to vps [Service] Type=oneshot ExecStart=/usr/bin/send-ip-to-vps Restart=no
以下是/usr/bin/send-ip-to-vps,真正执行的脚本
#!/bin/bash
privateKey=/home/john/.ssh/id_rsa
user=john
host=persistent.example.com
curl ident.me -s -o /tmp/currentIP.txt >> /dev/null
echo >> /tmp/currentIP.txt
# 获取当前的IP地址
scp -i ${privateKey} /tmp/currentIP.txt ${user}@${host}:/home/${user}/
# 将文件copy到远程服务器
exit $?
以root用户手动执行一次/usr/bin/send-ip-to-vps,把服务器的公钥添加到信任列表。随后执行systemctl enable send-ip-to-vps.timer,启用这个timer即可,在systemctl list-timers中可以看到启用的timer的情况,使用Surface连接persistent.example.com即可看到currentIP.txt