第十四章 定時任務crond 服務
一、crond概念
crond是Linux系統中用來定期執行命令或指定程序任務的一種服務(軟件)。
crond服務默認情況是每分鐘執行,服務會每分鐘檢查系統中是否有需要執行的定時任務,如果有,則根據事先定義好的規則來執行這個定時任務。
crond服務最小時間是分鐘,秒級任務crond服務自身無能爲力,但可通過方法來實現。
Linux如查要實現秒級任務的方法:
(1)自已寫守護進程
(2)自己寫shell循環
(3)Quartz來實現
(4)在crond服務中加入sleep 數字來實現
例:* * * * * sleep 3; /bin/date
二、crond服務的作用
一般運維要求:
7*24小時提供服務,是一般網站的基本特徵。
重要數據需每天備份。
凌晨備份,持續是間長
crond服務==鬧鐘
三、Linux系統定時任務的分類
1、系統自身定時執行的任務
ll /etc/ | grep cron
-rw-------. 1 root root 541 Nov 23 2013 anacrontab
drwxr-xr-x. 2 root root 4096 Jan 2 13:23 cron.d
drwxr-xr-x. 2 root root 4096 Jan 1 23:59 cron.daily
-rw-------. 1 root root 0 Nov 23 2013 cron.deny
drwxr-xr-x. 2 root root 4096 Jan 1 23:43 cron.hourly
drwxr-xr-x. 2 root root 4096 Jan 1 23:58 cron.monthly
-rw-r--r--. 1 root root 457 Sep 27 2011 crontab
drwxr-xr-x. 2 root root 4096 Sep 27 2011 cron.weekly
2、用戶定時執行的任務
crontab -l
#time sync by mybjb at 2017-01-23
*/10 * * * * /usr/sbin/ntpdate 210.72.145.44 > /dev/null2>&1
四、常用用用戶定時任務命令
1、at:適合執行一次就結束的調度任務(突發性任務,不重要)
(1)需要atd服務
chkconfig --list atd
atd 0:off 1:off 2:off 3:off 4:off 5:off 6:off
(2)格式:
at [參數] [時間]
at> 執行的指令
退出at命令 ctrl+d
(3)參數:
-m :當指定的任務被完成之後,將給用戶發送郵件,即使沒有標準輸出
-I :atq的別名
-d :atrm的別名
-v :顯示任務將被執行的時間
-c :打印任務的內容到標準輸出
-V :顯示版本信息
-q :後面加<列隊> 使用指定的列隊
-f :後面加<文件> 從指定文件讀入任務而不是從標準輸入讀入
-t :後面<時間參數> 以時間參數的形式提交要運行的任務
(4)時間格式:
a、HH:MM
說明:在今日的 HH:MM 時刻進行,若該時刻已超過,則明天的 HH:MM 進行此任務。
ex> 04:00
b、HH:MM YYYY-MM-DD
說明:規定在某年某月的某一天的特殊時刻進行該項任務
ex> 04:00 2009-03-17
c、HH:MM[am|pm] [Month] [Date]
說明:規定在某年某月某日的某時刻進行該項任務
ex> 04pm March 17
d、HH:MM[am|pm] + number[minutes|hours|days|weeks]
說明:規定在某個時間點再加多少時間後才進行該項任務
ex> now + 5 minutes
ex> 04pm + 3 days
(5)示例
例1:三天後的下午 5 點鍾執行 /bin/ls
# at 5pm + 3 days
at> /bin/ls
at> ctrl+d
例2:明天17點鐘,輸出時間到指定文件內
# at 17:20 tomorrow
at> date > /root/doiido.log
at> ctrl+d
2、anacron:適合於非7*24小時開機的服務器(如開機執行,不重要)
會檢測停機期間沒有執行的任務,在開機後一次性執行一遍。
(1)配置文件 /etc/anacrontab
(2)格式:
period delay job-identifier command
period — 命令執行的頻率(天數)
delay — 延遲時間(分鐘)
job-identifier — 任務的描述,在目錄/var/spool/anacron中生成一個以job-identifier命名的時
間戳文件的名稱,只能包括非空白的字符(除斜線外)。
command — 要執行的命令
(3)啓動/停止服務
/sbin/service anacron start 啓動該服務
/sbin/service anacron stop 停止該服務
(4)示例
cat /etc/anacrontab
#period delay job-identifier command
1 5 cron.daily nice run-parts /etc/cron.daily
7 25 cron.weekly nice run-parts /etc/cron.weekly
@monthly 45 cron.monthly nicerun-parts /etc/cron.monthly
注:monthly 就是一個月( 30 天)
3、crontab
crond是守護進程,crondtab是命令
(1)語法 crontab(選項)(參數)
(2)選項
-e:編輯該用戶的計時器設置(查看的文件是/var/spool/cron/<用戶名稱>,會進行語法檢查);
-l:列出該用戶的計時器設置(查看的文件是/var/spool/cron/<用戶名稱>);
-r:刪除該用戶的計時器設置;
-u <用戶名稱>:指定要設定計時器的用戶名稱。
(3)系統任務調度
a、配置文件: /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=""
HOME=/
# run-parts
51 * * * * root run-parts /etc/cron.hourly
24 7 * * * root run-parts /etc/cron.daily
22 4 * * 0 root run-parts /etc/cron.weekly
42 4 1 * * root run-parts /etc/cron.monthly
前四行是用來配置crond任務運行的環境變量,
第一行SHELL變量指定了系統要使用哪個shell,這裏是bash
第二行PATH變量指定了系統執行命令的路徑
第三行MAILTO變量指定了crond的任務執行信息將通過電子郵件發送給root用戶,如果MAILTO變量的值爲空,則表示不發送任務執行信息給用戶
第四行的HOME變量指定了在執行命令或者腳本時使用的主目錄。
run-parts表示後面接的是文件夾,要執行該文件夾內所有腳本。如果不寫run-parts,則要直接寫命令或腳本的全路徑。
b、查看/etc/crontab文件
cat /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
# For details see man 4 crontabs
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 -23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6)(Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to beexecuted
(4)、用戶任務調度
a、配置文件:
所有用戶定義的crontab文件都被保存在/var/spool/cron目錄中。其文件名與用戶名一致,
b、使用者權限文件如下:
/etc/cron.deny 該文件中所列用戶不允許使用crontab命令
/etc/cron.allow 該文件中所列用戶允許使用crontab命令
/var/spool/cron/ 所有用戶crontab文件存放的目錄,以用戶名命名
c、查看root用戶定時任務文件
cat /var/spool/cron/root
#time sync by myLinux93.85 at 2017-01-05
*/60 * * * * /usr/sbin/ntpdate 10.108.68.100 > /dev/null2>&1
4、crontab使用格式
(1)系統定時任務格式
a、系統定時任務規則格式分爲7段,用空格分隔。
前5段爲時間設定段,第6段爲用戶名,第7段爲所要執行的命令或腳本任務。
b、基本格式:
* * * * * user cmd
c、說明:
cmd可以是命令或腳本的全路徑,也可以是run-parts文件夾。
系統定時任務配置文件/etc/crontab只能由root用戶修改。
(2)用戶定時任務格式
a、用戶定時任務規則格式分爲6段,用空格分隔。
前5段爲時間設定段,第6段爲所要執行的命令或腳本任務。
b、基本格式:
* * * * * cmd # minute |hour | day of month | month | day of week | command
c、說明:
(i)cmd爲要執行的命令或腳本,必須要寫全口含路徑。如/bin/sh /wddg/test.sh。
(ii)每段之間必須要有一個空格。
(iii)時間段記憶口決:分時日月周
(iv)周和日儘量不要同時用,否則可能達不到想要的效果。
(v)cmd命令最好在命令行用tab補全後複製,
d、符號含義:
*:星號,表示任意時間。
分位是*表示每分(等價於00-59),時位*表示每小時(等價於00-23),同理,每天,每月,每週。
00 23 * * * cmd 表示每天23:00執行cmd
-:減號,分隔符,表示一個時間範圍或區間段。
如時位17-19表示每天17、18、19點。
00 17-19 * * * cmd 表示每天17:00、18:00、19:00分別執行cmd
,:逗號,表示枚舉分隔時段,可以和“-”同時使用。
如17,20,22表示每天17點,20點,22點。
30 3-5,17-19 * * * cmd 表示每天3:30、4:30、5:30、17:30、18:30、19:30分別執行cmd
/n:n代表數字,表示每隔n單位時間。
如分位上是*/10,表示每10分鐘,也可寫爲0-59/10
* */4 * * * cmd 表示每4小時執行一次cmd。
5、crontab依賴的服務
chkconfig --list crond
crond 0:off 1:off 2:on 3:on 4:on 5:on 6:off
/etc/init.d/crond status
crond (pid 3170) isrunning...
6、crontab示例
(1)編輯用戶定時任務(root和指定用戶)
root用戶:
crontab -e
#每小時查看磁盤空間情況,寫入/wddg/df.log文件中
00 * * * * /bin/df -h >> /wddg/df.log
指定用戶:
crontab -u wddg -e
(2)每天凌晨3:30和中午12:30執行/wddg/test.sh腳本
30 3,12 * * * /bin/sh /wddg/test.sh
(3)每6小時的半點執行執行/wddg/test.sh腳本
30 */6 * * * * /bin/sh /wddg/test.sh
(4)每天8-18點之間每2小時的半點執行/wddg/test.sh腳本
30 8-18/2 * * * /bin/sh /wddg/test.sh
(5)每天21:30重啓apache服務
30 21 * * * /var/apache/bin/apachectl graceful
(6)每月的1、10、22號的凌晨4:45分重啓apache服務
45 4 1,10,22 * * /var/apache/bin/apachectl graceful
(7)每週六、日的凌晨1:10分重啓apache服務
10 1 * * 6,0 /var/apache/bin/apachectl graceful
(8)每天的18-23點的整點和半點(也可以說每隔30分鐘)重啓apache服務
0,30 18-23 * * * /var/apache/bin/apachectl graceful
(9)每小時的整點重啓apache服務
00 */1 * * * /var/apache/bin/apachectl graceful
(10)晚上23點和早上0-7點的每分鐘都重啓apache服務
* 23,00-07/1 * * * /var/apache/bin/apachectl graceful
這題的結果是不規範的,也是不對的。並不表示晚上23點和早上0-7點的每小時都重啓apache服務。由於第1列是*,表示是每分鐘都執行。
(11)每年4月的每週一到週三每天上午11:00重啓apache服務
00 11 * 4 1-3 /var/apache/bin/apachectl graceful
(12)每分鐘打印一次自已的姓名到/wddg/log/name.log文件中
crontab -e
#print name to /wddg/log/name.log
* * * * * /bin/echo 'wddg' >> /wddg/log/name.log
(13)每週六、週日上午9:00和下午14:00通過腳本打印當天日期,格式yyyy-mm-dd
vi /wddg/printDate.sh
echo `date '+%Y-%m-%d'` >> /wddg/log/date.log > /dev/null2>&1 #%F也可以
crontab -e
#print date /wddg/log/date.log
00 09,14 * * 0,6 /bin/sh /wddg/printDate.sh
crontab -l
7、crontab日誌
日誌文件位置/var/log/cron*
ll /var/log/cron*
-rw-------. 1 root root 280238 Jan 25 09:45 /var/log/cron
-rw-------. 1 root root 577110 Jan 1 03:16 /var/log/cron-20170101
-rw-------. 1 root root 585344 Jan 8 03:52 /var/log/cron-20170108
-rw-------. 1 root root 597732 Jan 15 03:49 /var/log/cron-20170115
-rw-------. 1 root root 593889 Jan 22 03:20 /var/log/cron-20170122
五、crontab書寫注意事項(生產環境定時任務專業寫法)
(1)寫爲定時任務時要加上必要的註釋(最好是英文註釋,Linux對中文支持不好)。
格式:什麼人、什麼時間、因爲什麼(需求方)、做了什麼事。可以讓人容易理解任務的信息,提升工作效率。
(2)執行shell腳本任務前加/bin/sh
因爲創建的新文件默認權限是644,有時候,忘了爲腳本設置可執行權限(x),結果任務無法執行。加上/bin/sh可以保證任務正常執行。
(3)在執行shell腳本的定時任務結尾加>/dev/null2>&1
a、標準輸入輸出設備
/dev/null:是系統的空設備(也就是黑洞)
0:表示標準輸入
1:表示標準輸出
2:表示標準錯誤
b、重定向
2>&1 :把標準錯誤重定向到標準輸出
>/dev/null 2>&1等價於1>/dev/null 2>/dev/null也等價於&>/dev/null
c、郵件服務容易導致郵件臨時目錄中小文件過多
由於CentOS5.x默認安裝並開啓郵件服務,如查不加>/dev/null 2>&1,有可能產生大量輸出信息,導致郵件臨時目錄/var/spool/clientmqueue文件數猛增,佔用大量inode節點。CentOS6.x雖然默認不安裝郵件服務,但有可能以後會手動安裝郵件服務,也會導致上述問題。
具體過程如下:
當定時任務執行時,會根據/etc/crontab文件中MAILTO="root"這個配置選項給系統發一封郵件。Linux系統默認郵件服務是sendmail,經常是關閉的,所以定時任務發送的郵件就會臨時堆在/var/spool/clientmqueue目錄中,時間長了該目錄下的小文件會有委多,導致inode消耗完了,無法寫文件了。
d、文件過多時,rm –f * 刪除會報文件過多錯誤,需用ls(或find )| xargs rm –f來刪除。
e、定時任務執行的如果是命令,並肯已經有重定向或追加符號的,一般要測試一下加與不加>/dev/null 2>&1,看具體執行結果,有時是不行的。
(4)在指定用戶下執行相關定時任務
(5)規範腳本存放的目錄
(6)不要在屏幕輸出,可以輸出到指定日誌文件中
(7)定時任務最好都用腳本。cron中直接用命令,則命令中的%要轉義,否則報錯,但調用腳本則沒有這個問題。
超過2行的命令執行,最好寫成腳本,在定時任務是執行腳本。
不規範寫法:
* * * * * sleep 1;echo "abc" >>/wddg/test.log
規範寫法:
vi /wddg/test.sh
sleep 1
echo "abc" >>/wddg/test.log
* * * * * /bin/sh /wddg/test.sh >/dev/null 2>&1
(8)配置定時任務要規範操作
a、首先在命令行操作,成功後直接複製命令到腳本中,防止敲錯。
b、然後,在命令行用定時任務中腳本的寫法測試腳本正常後,再通過複製方式將腳本路徑寫入cron中。
c、最後,在測試環境中測試,通過後纔在正式環境中規範部署。
(9)命令和腳本要用全路徑
/bin/sh /wddg/test.sh
(10)使用tar等打包命令時,最好是切換到要打包目錄的上一級目錄再執行打包命令。不要從根目錄打起。
六、生產場景工作中調試定時任務的方法
1、調試時,把任務執行頻率調快一點,看能否執行,沒有問題了,在改成需要的任務執行時間。
2、調整系統時間來調試任務(不能用於生產環境)。
示例:週三的凌晨2:00執行,這時可以把測試環境時間調整爲週三的凌晨1:55分(不要太近,至少5分鐘時差)。
3、通過腳本日誌輸出調試定時任務。
可要腳本里輸出日誌,也可以輸出到日誌文件
4、注意一些任務命令帶來的問題
已經有重定向或追加符號的,不加>/dev/null 2>&1,
5、注意環境變量導致的定時任務故障
一般情況下,定時任務只能少數系統環境變量,所以定時任務在調用環境變量時, 應在腳本中先加載系統環境變量
文件或先定義環境變量。
6、通過crond定時任務服務日誌調試定時任務。
tail –f /var/log/cron*
7、其它稀奇大古怪的問題調試方法
如:直接命令行執行無問題,但放到定時任務就不行。此類問題主要是多看日誌。