今天这篇文章是用Java的方式去修改Linux服务器当中的crontab 定时任务。
首先我们简单的了解一下crontab当中的几个命令
# 查看当前用户的定时任务
crontab -l
# 编辑定时任务
crontab -e
# 删除定时任务 默认删除 /var/spool/cron/ 目录下面当前用户crontab文件
crontab -r
回到正文。
一开始 我是这样实现的,逻辑如下:
1 解析前台传过来的时间戳参数,获取到时分秒内容
2 写入文件 /var/spool/cron/sdata
内容是 0 9 * * * /home/sdata/anaconda3/bin/python /home/sdata/price.py
代表每天9点整的时候 使用解释器/home/sdata/anaconda3/bin/python (这里用的是绝对路径) 去执行 /home/sdata/price.py文件
public void updateCron(String start_time) {
FileWriter fw = null;
try {
// 将时间戳转换为时分秒
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
Long aLong = new Long(start_time);
Date date = new Date(aLong);
String format = simpleDateFormat.format(date);
String[] split = format.split(":");
// 文件内容
StringBuilder sb = new StringBuilder();
sb.append("0 ").append(split[0]).append(" * * * /home/sdata/anaconda3/bin/python /home/sdata/price.py");
// 写入文件
String filePath = "/var/spool/cron/sdata";
File file = new File(filePath);
if(!file.exists())
{
file.createNewFile();
}
fw = new FileWriter(filePath);
fw.write(sb.toString());
} catch (Exception e) {
log.error("修改sdata定时任务时间失败:" + e.getMessage());
} finally {
try {
if(null != fw) {
fw.close();
}
}catch (Exception e) {
log.error(e.getMessage());
}
}
}
结果是文件确实修改成功了,但是定时任务到时间不会执行。
一开始我感觉可能是权限啊用户组方面的问题,结果也改了还是行不通。
随后我又猜测可能是改完文件之后需要重启定时任务吧,但是crond进程每分钟会定期检查是否有要执行的任务的,如果有要执行的任务,则自动执行该任务
(可以通过 tail -f /var/log/cron 这个命令进行查看cron任务日志)。
所以这种猜测也是不成立的。而且重启定时任务涉及到权限的问题。一般只有root用户是可以的。
网上关于这方面的内容也是很少,但也找到了一篇博主写的内容作为参考。
https://blog.csdn.net/ArvinZhangjia/article/details/127302063
于是乎代码实现是下面这样的
为了测试方便,我把参数改成了crontab表达式,逻辑如下:
1 创建一个txt 和 sh文件
2 txt文件当中写入内容 0 9 * * * /home/admin/files/scheduleTask.sh
3 sh文件当中写入内容 #!/usr/bin/bash" + “\n” + "/usr/bin/python2.7 /home/admin/test.py
4 赋予sh文件可执行权限
5 将 txt文件加入到crontab任务当中
其中最关键的还是最后一步
crontab file 代表使用者可以将所有的设定先存放在文件中,用 crontab file 的方式来设定执行时间
逻辑执行下来就是 定时任务先去执行sh文件 而sh文件又去执行里面的py文件
public void test2(@Param("cron") String cron){
String path = "/home/admin/files/";
// String cron = "0 16 * * *";
File file = new File(path + "scheduleTask.txt");
File shFile = new File(path + "scheduleTask.sh");
FileWriter fileWriter = null;
FileWriter shellWriter = null;
try {
// 创建文件
if (!file.exists()) {
file.createNewFile();
shFile.createNewFile();
}
// txt文件 写入定时任务时间 和 执行文件
fileWriter = new FileWriter(file);
fileWriter.write("");
fileWriter.write(cron + " " + shFile + "\n");
fileWriter.flush();
// sh文件 写入执行内容
shellWriter = new FileWriter(shFile);
shellWriter.write("#!/usr/bin/bash" + "\n" + "/usr/bin/python2.7 /home/admin/test.py");
shellWriter.flush();
// 赋予权限
executeNewFlow("chmod 777 " + shFile);
executeNewFlow("crontab " + file);
} catch (Exception e) {
logger.error(e.getMessage());
} finally {
try {
if (null != fileWriter) {
fileWriter.close();
}
if(null != shellWriter) {
shellWriter.close();
}
} catch (Exception e) {
logger.error(e.getMessage());
}
}
}
public void executeNewFlow(String cmd) throws IOException, InterruptedException {
Runtime.getRuntime().exec(cmd).waitFor();
}
改进之后是这样的:
1 创建一个txt文件,写入内容 0 9 * * * /home/sdata/anaconda3/bin/python /home/sdata/price.py
2 将这个文件加入到crontab任务当中
public void test(@Param("cron") String cron){
String path = "/home/admin/files/";
// String cron = "0 16 * * *";
File file = new File(path + "scheduleTask.txt");
FileWriter fileWriter = null;
try {
// 创建文件
if (!file.exists()) {
file.createNewFile();
}
// txt文件 写入定时任务时间 和 执行文件
fileWriter = new FileWriter(file);
fileWriter.write("");
fileWriter.write(cron + " /usr/bin/python2.7 /home/admin/test.py \n");
fileWriter.flush();
// 加入定时任务
executeNewFlow("crontab " + file);
} catch (Exception e) {
logger.error(e.getMessage());
} finally {
try {
if (null != fileWriter) {
fileWriter.close();
}
} catch (Exception e) {
logger.error(e.getMessage());
}
}
}