第5节. 计划任务实现

一次性任务用的少:at这个包提供了at和batch两个命令

image-20220809113505458

at用的多一点,batch基本不用。其实at也不怎么用

image-20220809113745231

atq和atrm是at的扩展用法

image-20220809113811024

atd.service必须是启动状态,这是前提

image-20220809113841143

centos6上的atd服务:

image-20220809113948606

image-20220809114004241

at一般用法就是跟一个时间执行cmd

image-20220809114254801

at -t的格式1和at 后不带-t的格式2

image-20220809114322475

image-20220809114628194

at回车会等STDIN,at -l查看计划任务,ctrl d 安全退出

image-20220809133254738

1就是第一个任务

at -c 1可以查看具体任务细节,上面都是各种变量,最下面才是任务明细

image-20220809133440033

等到时间了,任务执行完毕,就没了

image-20220809133510444

at了3个命令,第一个创建文件执行了,但是后面两个ls和hostname怎么理解呢,在哪里体现呢

image-20220809133705610

计划任务是在未来的时间执行的,ls和hostname是在当前终端tty上运行的。

而你不能确定你将来就在这个tty上,说不定别人正好撞到这个tty上了,就看到了ls和hostname执行的结果了。就是你执行的命令,别人看到了,这就不合理了。

所以基于以上道理,计划任务的STDOUT标准输出不会在屏幕上打印的。虽然没有输出到屏幕,但是以邮件的形式发给你了。

由于刚才是以root用户执行的,所以邮件就发到了root:

image-20220809134113899

image-20220809134217641

所以方法论来了,计划任务的脚本,一般不推荐有输出,而是所有输出都扔到日志或在/dev/null里,这话我就不认同哈哈,因为我的py脚本很多还是保留了print的,这些屏幕上看得到的,当然crontab去执行的化,自然屏幕看不到了。

不对,视频老师的意思的,crontab里的脚本不要有标准输出,否则会给你发送大量邮件,emmm,这话也不对,有时候正要考这些邮件当作日志来分析是否运行了。

不过,确实很多文章上的crontab都是由 /xxx/xxx/ /xxx/xxx > /dev/null的,看来不要发邮件才是比较好的一个做法。

image-20220809134932488

ctrl c是强行终止

image-20220809135041015

然后reboot重启,这些计划任务还在吗?

image-20220809135106507

重启后发现at -l还在

image-20220809135138210

说明重启也不会影响at的任务,说明肯定是找一个地方存起来了。肯定不是内存里放了,肯定是放到磁盘上了。

磁盘上哪里呢?👇

image-20220809135241871

image-20220809135307533

a00003xxxx和a00004就是at -l看到的3和4编号。

image-20220809135348956

这个cat /va/spool/at/a00003xxx文件看到的正是at -c 3看到的

这个路径的权限只有root

image-20220809135626317

换个普通账号创建计划任务也是可以的

image-20220809143013611

然后wang账号的计划任务也是放在/var/spool/at路径下的

image-20220809143125125

对于wang账号来讲,/var/spool/at路径是没有权限的,但是确实将任务写进去了,说明at由SUID权限👇

image-20220809143231803

删除atrm或者at -d一个意思

image-20220809143354567

atrm -4说白就是把/var/spool/at的对应的文件删了

image-20220809143433489

同理,可以直接删文件,

image-20220809143511272

image-20220809150015335

noon:中午12点

midnigth:午夜12点,0点

teatime:下午茶时间,4点

tomorrow

now + xxx:现在往后多久时间

image-20220809150233952

-f

创建一个文件

image-20220809150318537

image-20220809150345911

-f 其实也就是利用重定向的效果:at 18:00 < atlist这样也行

image-20220809151248616

-m 告知计划任务有无执行

image-20220809150507766

把原来邮件删掉

image-20220809150735952

image-20220809150745774

1分钟后执行

image-20220809150641765

就是个空邮件告诉你执行了

image-20220809150936982

image-20220809151348692

白名单优于黑名单,如果wang既在白名单也在黑名单,白名单里有就不看黑名单了。

如果user2黑白里都没有,我分析就可以执行。

周期性任务用的多:crontab

对应的软件包比较多

image-20220809152100536

cronie是主要工具包

image-20220809152158472

image-20220809152218789

image-20220809152239373

上图的 crontd是主程序,运行后会自动周期运行计划任务。

上图的 /usr/bin/crontab # 是创建用户自己的计划任务的工具,区别于全局的/etc/crontab文件

centos6下的情况:

image-20220809152311695

crontabs是创建计划任务的工具

image-20220809152542622

image-20220809152618216

image-20220809152647336

用户自定义的计划任务

image-20220809152849386

通过crontab创建,后存放在/var/spool/cron下

这个/var/spool文件夹也是一个常用文件夹

image-20220809153005151

除了刚才的at和马上正在学习的cron还有mail邮件也都在这里。

cronie-anacron补充性的包,用的不多

image-20220809153050371

image-20220809153131558

image-20220809153138312

使用场景举例:

在家用电脑中安装了一个linux,这种PC台式机不像服务器一样24小时开机的,可能定期就会自动重启的。而加入计划任务是半夜执行的,而此时你关机了,就会导致计划任务没有执行,此时就有cronie-anacron来执行。

​ 当你开机后的一段时间,会自动检查时间已过了没有执行的任务,找个时间给你执行了。

通过查看/etc/crontab可知,里面的存在各种环境变量的

image-20220809153720117

而直接crontab -e去编辑用户自定义的任务,有时候就需要手动补上变量,比如我这种

image-20220809153825806

这都是报错,后来解决的方法👆,

然后/etc/crontab还有个地方说明下

image-20220809154009222

这个文件只有root才能读写,所以普通用户无法编辑,所以上面的user-name是root指定,意思就是这个计划任务是以某个普通用户来执行的。

写个磁盘空间告警

image-20220809160837021

以前不太理解为什么sed 要先找到再查找替换,为什么不直接查找替换,现在案例就来了

image-20220809161111459

先找到/dev/sda开头的(相当于做了一步过滤),再针对这些开头进行替换。它不是说真的要替换,如果真的要替换直接s#a#b#就好了,它是要过滤显示出结果,所以需要查找到再替换显示。

image-20220809161218635

这就找到最大值了。

image-20220809161902836

image-20220809161915193

将脚本写到crontab里

image-20220809162007169

第一个*号的意思:

1,10,30 表示每小时的第1、10、30分钟

* 表示每分钟

*/10 表示每10分钟

待会用wang普通账号去执行crontab,就是user-name写成wang,所以要看下脚本是否有权限

image-20220809162417616

这样脚本wang用户就可以执行了。

然后就是 每分钟,1-5工作日,wang 去执行脚本,0或者7表示周日

image-20220809162527172

然后跟踪下cron的日志

image-20220809162648175

解释下面的任务

image-20220809162814752

就是 30分 2点 1,10,20号 每月 周六或周日

问题来了,这个1号10号20号万一不是周末了,他们之间是并取还是或的关系呢?

通过man 5 crontab可以找到逻辑关系,搜下note

image-20220809163625760

either就是也,plus就是加上,这些就说明了是 或的关系。

image-20220809163800068

所以每个月的1、10、20号会执行,然后每周的周6和周日也会执行。

问题来了,如果我就要并且呢,计划任务没有这功能,就需要在脚本里去判断

image-20220809163939964

然后脚本里去判断是否为周末,如果是就执行。这就是且的关系的落地。

image-20220809164020869

用这个命令获得今日是周几;👇man date

image-20220809164053693

通常计划任务不会放到这个/etc/crontab里,一般就是crontab -e那个用户就是哪个创建的。

crontab -e创建的时候,就系统就自然就知道是哪个用户创建的,所以格式上就有个默认的user-name不用写了,直接 * cmd

image-20220809164453024

image-20220809164537448

该文件已经有执行,所以就是CMD搞定

不通用户创建的crontab -e其实就是/var/spool/cron下的不同文件

image-20220809165418484

image-20220809165509402

crontab -l看自己的,看别人的加上 -u

删除某某用户的所有计划任务

image-20220809165648773

文件下的脚本都执行

image-20220809165922641

image-20220809170121908

image-20220809165945079

image-20220809170040621

每分钟,执行/data/scripts下的所有脚本,然后验证确实执行了:

image-20220809170207748

image-20220809170218777

image-20220809170306656

这个次序就是按ls的次序执行的

image-20220809170333804

验证上面的次序判定

image-20220809170447433

可见/usr/bin/run-parts /data/scripts 确实是按脚本存放路径的ls次序执行的。

系统本身就有的周期性任务

image-20220809170606807

image-20220809170625951

mlocate就是locate的依赖的默认数据库,而这个数据库是每天刷新一次的。就是靠这里。

为什么放到/etc/cron.daily下的这些脚本(这些logrotate、man-db.cron、mlocate都是独立的脚本),为啥这些就会daily每日执行呢,其实还需要有个cron去执行他们的。

image-20220809171544122

上图就是cron.hourly文件夹下的脚本都会执行的原因,因为有/etc/cron.d/0hourly去执行的。而daily文件夹下就不会执行,因为/etc/cront.d下没有对应的周期命令。

image-20220809172956537

但其实上面的可能是执行的,因为还有

image-20220809173110152

日志可以观察,也可以帮助还原误删除的计划任务

/var/log/cron

image-20220809172053473

image-20220809172312738

下次开机执行的方法,应该是等价于rc.local的。

image-20220809172401210

crontab -e 便捷

image-20220809172423440

重启后可见,确实执行了

image-20220809172535321

因为wall看不到广播效果,因为没法提前进到那个终端去等到广播信息

换一个方式

image-20220809172624710

image-20220809172642814

image-20220809172822433

多任务时间一致,可以用分号隔开,呵呵,要考虑前一条执行花费时间哦,第二条执行有延迟的。

image-20220809172712136

anacontab

image-20220809173110152

1表示1天执行一次,开机5分钟后自动运行 cron.daily

每天就是1

每周就是7

每月就是@monthly,

5 25 45就是开机后的5、25、45分钟后执行后面的脚本。

image-20220809174133949

45分钟随机延迟

服务器上这个anacron用的少

管理临时文件

centos6上的一些文件

image-20220809193109874

makewhatis就是手动做了makewhatis.cron

image-20220809193232016

mlocate.cron相关的信息,手动就是updatedb。

image-20220809193557648

tmpwatch是清除垃圾文件

image-20220809193707143

10天清理一次/tmp

30天清理一次/var/tmp

windows没有定时清理的功能

到了centos7就是一个服务专门来做这事了

image-20220809194059316

原来centos6这个路径下,在7上就没有哪个tmpwatch文件了:

image-20220809194208840

image-20220809194314554

image-20220809194758138

不希望wang执行计划任务

image-20220809194852702

image-20220809194931987

image-20220809195054693

image-20220809195018754

再写一个/etc/cront.allow

image-20220809195126573

image-20220809195148597

image-20220809195209050

白的黑的都有wang,其实就只看白的了

crontab -e就进去了👇

image-20220809195245020

image-20220809195332747

这个deny只是说不能编辑,原来如果有权限的时候编辑的计划任务还是会正常工作的。

crontab精确到s的方法

sleep可以精确到0.1s好像

但是你用sleep控制周期,就不是crontab里的每分钟--其实是到整点就执行了。sleep是真的等1s执行,那么如果之前的脚本本身执行就要花4s,那么用with os.popen阻塞的方式,其实就是5s钟才能一个周期了。而且存在队列不断加大的风险。

usleep是微妙级别的睡眠

image-20220809200026917

利用crontab定期同步时间

这个是取之我们的extmail里的一个案例:

image-20220809200151610

这是视频里老师的写法:

image-20220809200254360

上图有错误,所以wq退出会报错

image-20220809200437792

y重新edit为:

image-20220809200509264

据说&> /dev/null是一个好习惯,否则一堆垃圾邮件。

习题

image-20220809200905770

说是*/7不行,因为60/7除不尽,需要用sleep 420 来做,但你想想就是我说的,脚本执行如果要化10s,没关系,那也是脚本执行后sleep了7分钟才继续执行啊。所以两次周期就是严格的7分钟过了。

sleep也是有单位的

image-20220809202125672

image-20220809202113309

crontab里不要用%,这个踩过坑,当然%如果在py脚本里是没有问题的,

image-20220809202157166

有人想在crontab里写date +%F,这种就不行,换个思路,将date +%F写到脚本里,然后crontab里调用脚本就可以了。

还有就是上文提到过变量问题,或者叫二进制的执行文件要写绝对路径--但是有的遗漏的就是通过邮件看到日志提示

之前的坑记录如下,emmm原来慢慢吞吞都1年半下来了。太慢啦,不过这事写脚本,不算linux系统学习,也还说的过去。

image-20220809202643607

image-20220809202847600

image-20220809202856763

这个还是python脚本里调用了mtr命令,然后crontab报错找不到PATH变量

image-20220809203124611

而且,我都在py里的mtr也是写了绝对路劲的,但是就是不认,哈哈,最后还是加了一行path变量才好的。

image-20220809203313911

Copyright 🌹 © oneyearice@126.com 2022 all right reserved,powered by Gitbook文档更新时间: 2024-07-28 14:47:41

results matching ""

    No results matching ""