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