这段时间在为公司做一款手游的管理后台,在游戏数据统计方面,需要使用到 crontab
定时去触发php进行数据
统计。因为服务器有相关运维人员去维护的,所以每次需要增删改查
定时器时都要麻烦到运维人员。基于以上情况,
我在管理后台开发了一个基于web去维护crontab
的程序。
crontab预备知识
先来看下crontab
给出的指令支持
crontab file [-u user] #用指定的文件替代目前的crontab。
crontab - [-u user] #用标准输入替代目前的crontab.
crontab -l [user] #列出用户目前的crontab.
crontab -e [user] #编辑用户目前的crontab.
crontab -d [user] #删除用户目前的crontab.
crontab -c dir #指定crontab的目录。
crontab -l
会列出当前用户目前的crontab,但是它会全文列出,包括相关注释信息
root@ubuntu:~# crontab -l
# 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
* * * * * mkdir test
现在我们对crontab -l
添加grep
进行过滤,只匹配出已生效内容
root@ubuntu:~# crontab -l | grep ^[*1-9]
* * * * * mkdir test
编辑crontab内容,我们可以通过 crontab -e
执行文字编辑器来设定时程表,内定的文字编辑器是 vi
。或者
可以通过标准输入crontab -
来设定。例如
root@ubuntu:~# echo "* * * * * echo test" | crontab -
root@ubuntu:~#
root@ubuntu:~# crontab -l
* * * * * echo test
可以留意到,如果我们用标准输入把指令写入crontab
,它会重置掉之前的所有内容。我们可以在写入前,先把之前
的指令全部读取出来,然后把新的指令拼接到最后,接着再写入。代码如下
#!/bin/bash
crontab_comm=`echo test`
oldCrontabList=`crontab -l`
newCrontabList=`echo "${oldCrontabList}"; echo "${crontab_comm}"`
echo "${newCrontabList}" | crontab -
同样道理,如果我们要做删除某条指令操作,我们只需要把内容读出,然后把匹配到指令那一行删除,接着通过标准 输入从新把指令写入即可。
php管理crontab
有了以上思路我们就可以通过 php+exec 对 crontab 进行增删改查
。下面是核心的代码
<?php
class cron_mgr {
// 解析crontab内容
private function parse_crontab($crontab) {
$data = array();
foreach ($crontab as $cron) {
$tmp = array();
$slices = preg_split("/[\s]+/", $cron, 6);
if (count($slices) !== 6) continue;
$tmp['cmd'] = array_pop($slices);
$cron_time = implode(' ', $slices);
$tmp['cron'] = preg_split("/[\s]+/i",trim($cron_time));
$tmp['cron_str'] = $cron;
array_push($data, $tmp);
}
return $data;
}
// 读取生效的crontab指令
private function get_crontab() {
$retval = array();
$last_line = exec('crontab -l | grep ^[*1-9]', $retval);
return $retval;
}
// 读取crontab所有内容(包含注释)
private function get_crontab2() {
$retval = array();
$last_line = exec('crontab -l', $retval);
return $retval;
}
// 使用当前命令重置crontab
private function recharge_crontab($cmds) {
$cmds = implode("\n", $cmds);
$query = 'echo "'.$cmds.'" | crontab -';
$last_line = exec($query);
if ($last_line === "") {
return TRUE;
}
}
// 在crontab底部添加新的指令
private function add_crontab($cmds) {
$crontab = $this->get_crontab2();
$cmds = array_merge($crontab, $cmds);
return $this->recharge_crontab($cmds);
}
}
我这边管理后台效果图