在日常運維工作中, 經常會碰到以秒為單位去定時執行某些命令或監控指令碼的需求。 說到定時任務就要用到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 讓它每次開機都可以被執行 [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)本身也是需要一定時間的。如果對於精確度要求不高,推薦使用第二種方法。