在日常运维工作中, 经常会碰到以秒为单位去定时执行某些命令或监控脚本的需求。 说到定时任务就要用到crontab,通常来说,crontab的最小单位是分钟级别,要想实现秒级别的定时任务,就要进行特殊设置了。
测试:每隔2秒钟向/root/test.log文件输入"beijing is so good!", 下面介绍三种方法来实现秒级别的定时任务执行:
第一种方法
写一个触发的脚本,在触发脚本中使用死循环来解决此问题 [root@test ~]# cat kevin.sh #!/bin/bash while : ;do echo "beijing is so good!" >> /root/test.log sleep 2 done [root@test ~]# chmod 755 kevin.sh 可以把它放到计划任务使其运行 [root@test ~]# crontab -e * * * * * /bin/bash -x /root/kevin.sh >/dev/null 2>&1 等待这个计划任务执行后,就将计划任务中的此条目删除或注释!防止该计划条目无限制地执行下去(只需执行一次就可以,因为kevin.sh脚本里本身就有死循环) [root@test ~]# ps -ef|grep kevin.sh root 29839 29835 0 16:05 ? 00:00:00 /bin/sh -c /bin/bash -x /root/kevin.sh >/dev/null 2>&1 root 29842 29839 0 16:05 ? 00:00:00 /bin/bash -x /root/kevin.sh root 29852 16356 0 16:05 pts/0 00:00:00 grep kevin.sh [root@test ~]# crontab -e #* * * * * /bin/bash -x /root/kevin.sh >/dev/null 2>&1 最后把这个脚本放到 /etc/rc.local 让它每次开机都可以被运行 (手动在命令行执行, 后面最好加入&, 让其在后台运行, 即"/bin/bash -x /root/kevin.sh >/dev/null 2>&1 &") [root@test ~]# vim /etc/rc.local /bin/bash -x /root/kevin.sh >/dev/null 2>&1 验证(查看是不是每隔2秒在/root/test.log文件中写入了) [root@test ~]# tail -f /root/test.log beijing is so good! beijing is so good! beijing is so good! beijing is so good! beijing is so good! beijing is so good! beijing is so good! ......... ......... ======================================================================================================================== 温馨提示: 上面的kevin.sh脚本在第一次运行时千万不要执行"nohup /bin/bash /root/kevin.sh &", 即不要以这种方式放在后台执行, 否则会僵死!增加系统负载!! 例如很早之前用来监控sftp高可用中vip资源(172.16.51.193)的脚本,实时执行! 参考:https://www.cnblogs.com/kevingrace/p/7868049.html 1)第一台机器sftp-node01的操作 (172.16.51.191) [root@sftp-node01 ~]# cat /data/script/sftp_vip_monit.sh #!/bin/bash while [ "1" = "1" ] do NUM=`ip addr|grep 172.16.51.193|wc -l` if [ $NUM -eq 0 ];then echo "vip is not at this server" >/dev/null 2>&1 fi if [ $NUM -eq 1 ];then /usr/bin/rsync -e "ssh -p22" -avpgolr --progress --delete-before /data/sftp/mysftp/ root@172.16.51.192:/data/sftp/mysftp/ fi done [root@sftp-node01 ~]# chmod 755 /data/script/sftp_vip_monit.sh [root@sftp-node01 ~]# nohup sh /data/script/sftp_vip_monit.sh & //按ctrl+c结束 [root@sftp-node01 ~]# ps -ef|grep monit root 10581 22167 0 19:42 pts/0 00:00:00 grep monit root 15113 1 8 17:15 ? 00:13:00 sh sftp_vip_monit.sh 2)第二台机器sftp-node02 (172.16.51.192) [root@sftp-node02 ~]# cat /data/script/sftp_vip_monit.sh #!/bin/bash while [ "1" = "1" ] do NUM=`ip addr|grep 172.16.51.193|wc -l` if [ $NUM -eq 0 ];then echo "vip is not at this server" >/dev/null 2>&1 fi if [ $NUM -eq 1 ];then /usr/bin/rsync -e "ssh -p22" -avpgolr --progress --delete-before /data/sftp/mysftp/ root@172.16.51.191:/data/sftp/mysftp/ fi done [root@sftp-node02 ~]# chmod 755 /data/script/sftp_vip_monit.sh [root@sftp-node02 ~]# nohup sh /data/script/sftp_vip_monit.sh & //按ctrl+c结束 [root@sftp-node02 ~]# ps -ef|grep monit root 10581 22167 0 19:42 pts/0 00:00:00 grep monit root 15113 1 8 17:15 ? 00:13:00 sh sftp_vip_monit.sh 这种操作方式,虽然可以实现实时执行,但可能会造成僵死,加大系统负载! 可以参考上面第一种方式那样进行调整,实现每1秒钟来执行这个监控脚本!
第二种方法
和第一种方法类似,只不过感觉比第一种更便捷一些。
[root@test ~]# vim kevin.sh #!/bin/bash for((i=1;i<=20;i++));do echo "beijing is so good!" >> /root/test.log sleep 2 done 然后添加脚本执行权限, 写入的crontab里每分钟执行一次 [root@test ~]# chmod 755 kevin.sh [root@test ~]# crontab -e * * * * * /bin/bash -x /root/kevin.sh >/dev/null 2>&1 [root@test ~]# ps -ef|grep kevin.sh root 30515 30514 0 16:27 ? 00:00:00 /bin/sh -c /bin/bash -x /root/kevin.sh >/dev/null 2>&1 root 30516 30515 0 16:27 ? 00:00:00 /bin/bash -x /root/kevin.sh root 30527 16356 0 16:27 pts/0 00:00:00 grep kevin.sh [root@test ~]# tail -f /root/test.log beijing is so good! beijing is so good! beijing is so good! beijing is so good! beijing is so good! beijing is so good! ........
第三种方法
使用crontab计划任务来直接实现!经验证,这种方式是最靠谱,最稳妥的!
[root@test ~]# cat /root/kevin.sh #!/bin/bash echo "beijing is so good!" >> /root/test.log 添加脚本执行权限,并配置到crontab计划任务里(使用&& 或者 ;都是一样的效果)。思路:先过一分钟执行第一次,接着就是每隔2秒钟执行一次。 [root@test ~]# chmod 755 /root/kevin.sh [root@test ~]# crontab -e * * * * * /bin/bash -x /root/kevin.sh >/dev/null 2>&1 * * * * * sleep 2 && /bin/bash -x /root/kevin.sh >/dev/null 2>&1 * * * * * sleep 4; /bin/bash -x /root/kevin.sh >/dev/null 2>&1 * * * * * sleep 6; /bin/bash -x /root/kevin.sh >/dev/null 2>&1 * * * * * sleep 8; /bin/bash -x /root/kevin.sh >/dev/null 2>&1 * * * * * sleep 10; /bin/bash -x /root/kevin.sh >/dev/null 2>&1 * * * * * sleep 12; /bin/bash -x /root/kevin.sh >/dev/null 2>&1 * * * * * sleep 14; /bin/bash -x /root/kevin.sh >/dev/null 2>&1 * * * * * sleep 16; /bin/bash -x /root/kevin.sh >/dev/null 2>&1 * * * * * sleep 18; /bin/bash -x /root/kevin.sh >/dev/null 2>&1 * * * * * sleep 20; /bin/bash -x /root/kevin.sh >/dev/null 2>&1 * * * * * sleep 22; /bin/bash -x /root/kevin.sh >/dev/null 2>&1 * * * * * sleep 24; /bin/bash -x /root/kevin.sh >/dev/null 2>&1 * * * * * sleep 26; /bin/bash -x /root/kevin.sh >/dev/null 2>&1 * * * * * sleep 28; /bin/bash -x /root/kevin.sh >/dev/null 2>&1 * * * * * sleep 30; /bin/bash -x /root/kevin.sh >/dev/null 2>&1 * * * * * sleep 32; /bin/bash -x /root/kevin.sh >/dev/null 2>&1 * * * * * sleep 34; /bin/bash -x /root/kevin.sh >/dev/null 2>&1 * * * * * sleep 36; /bin/bash -x /root/kevin.sh >/dev/null 2>&1 * * * * * sleep 38; /bin/bash -x /root/kevin.sh >/dev/null 2>&1 * * * * * sleep 40; /bin/bash -x /root/kevin.sh >/dev/null 2>&1 * * * * * sleep 42; /bin/bash -x /root/kevin.sh >/dev/null 2>&1 * * * * * sleep 44; /bin/bash -x /root/kevin.sh >/dev/null 2>&1 * * * * * sleep 46; /bin/bash -x /root/kevin.sh >/dev/null 2>&1 * * * * * sleep 48; /bin/bash -x /root/kevin.sh >/dev/null 2>&1 * * * * * sleep 50; /bin/bash -x /root/kevin.sh >/dev/null 2>&1 * * * * * sleep 52; /bin/bash -x /root/kevin.sh >/dev/null 2>&1 * * * * * sleep 54; /bin/bash -x /root/kevin.sh >/dev/null 2>&1 * * * * * sleep 56; /bin/bash -x /root/kevin.sh >/dev/null 2>&1 * * * * * sleep 58; /bin/bash -x /root/kevin.sh >/dev/null 2>&1 [root@test ~]# tail -f /root/test.log beijing is so good! beijing is so good! beijing is so good! beijing is so good! beijing is so good! beijing is so good! beijing is so good! beijing is so good! beijing is so good! .......... ..........
上面介绍的三种方法,比较倾向于推荐第三种方法,因为前两种方法并不是严格的间隔2秒执行的,可能会大于2秒,因为执行脚本(kevin.sh)本身也是需要一定时间的。如果对于精确度要求不高,推荐使用第二种方法。