crond是linux下用來週期性的執行某種任務或等待處理某些事件的一個守護進程,與windows下的計劃任務相似,當安裝完成操做系統後,默認會安裝此服務工具,而且會自動啓動crond進程,crontab依賴的服務就是crond,crond進程每分鐘會按期檢查是否有要執行的任務,若是有要執行的任務,則自動執行該任務。這個crond定時任務服務就至關於咱們生活中的鬧鐘!java
因爲crond 是Linux的內置服務,但它不自動起來,能夠用如下的方法啓動、關閉這個服務:node
1
2
3
4
5
6
7
8
|
/sbin/service
crond start
//
啓動服務
/sbin/service
crond stop
//
關閉服務
/sbin/service
crond restart
//
重啓服務
/sbin/service
crond reload
//
從新載入配置
或者使用下面的命令:
/etc/init
.d
/crond
start
/etc/init
.d
/crond
restart
/etc/init
.d
/crond
stop
|
設置crond服務開機自啓動:linux
1
|
[root@gin tmp]
# chkconfig crond on
|
特殊須要:crond服務搞不定了,通常工做中寫腳本守護程序執行:web
1
2
3
4
5
6
|
[root@gin tmp]
# cat cron.sh
while
true
do
echo
"I am Bruce Lee"
sleep
1
done
|
程序文件:程序代碼組成,可是沒有在計算機內執行。當前沒有執行。shell
守護程序或守護進程:進程就是所算機中正在執行的程序,守護進程就是保護正在一直運行的程序。apache
Linux下的任務調度分爲兩類,系統任務調度和用戶任務調度。vim
系統週期性所要執行的工做,好比寫緩存數據到硬盤、日誌清理等。在/etc目錄下有一個crontab文件,這個就是系統任務調度的配置文件。windows
/etc/crontab文件包括下面幾行:緩存
1
2
3
4
5
6
7
8
9
|
SHELL=
/bin/bash
PATH=
/sbin
:
/bin
:
/usr/sbin
:
/usr/bin
MAILTO=root
HOME=/
# run-parts
01 * * * * root run-parts
/etc/cron
.hourly
02 4 * * * 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任務運行的環境變量bash
第一行SHELL變量指定了系統要使用哪一個shell,這裏是bash
第二行PATH變量指定了系統執 行命令的路徑
第三行MAILTO變量指定了crond的任務執行信息將經過電子郵件發送給root用戶,若是MAILTO變量的值爲空,則表示不發送任 務執行信息給用戶
第四行的HOME變量指定了在執行命令或者腳本時使用的主目錄。第六至九行表示的含義將在下個小節詳細講述。這裏不在多說。
用戶按期要執行的工做,好比用戶數據備份、定時郵件提醒等。用戶可使用 crontab 工具來定製本身的計劃任務。全部用戶定義的crontab 文件都被保存在 /var/spool/cron目錄中。其文件名與當前用戶名一致。
嚴格的說,linux系統下的定時任務軟件還真很多,例如:at , crontab , anacron。
at:適合僅執行一次就結束的調度任務命令,如:某天晚上須要處理一個任務,僅僅是這一天的晚上,屬於突發性的工做任務。要執行at命令,還須要啓動一個名爲atd的服務才行。在生產環境中此須要會不多用到。所以,建議不要深刻研究!
提示:
1:咱們所說的crond服務是運行的程序,而crontab命令用戶用來設置定時規則的命令
2:crond服務是企業生產工做中經常使用的重要服務,at和anacron不多使用,能夠忽略
3:幾乎每一個服務器都會用到crond服務
crontab經常使用的使用格式有以下兩種:
1
2
|
crontab
[-u user] [
file
]
crontab
[-u user] [-e|-l|-r |-i]
|
選項含義以下:
參數名稱 |
含義 |
指定示例 |
-l |
顯示用戶crontab文件內容,l即list |
crontab -l |
-e |
編輯某個用戶的crontab文件內容。若是不指定用戶,則表示編輯當前用戶的crontab文件。 |
crontab -e |
-i |
在刪除用戶的crontab文件時給確認提示。 |
crontab -ri |
-r |
從/var/spool/cron目錄中刪除某個用戶的crontab文件,不指定用戶,則刪除當前用戶的crontab文件。 |
crontab -r |
-u |
用來設定某個用戶的crontab服務,此參數通常由root用戶來運行 |
crontab -u root -l |
經常使用的選項命令爲 l and e!crontab -e 至關於 vi /var/spool/cron/root ; crontab -l 至關於 cat /var/spool/cron/root
使用者權限文件:
文件 |
說明 |
/etc/cron.deny |
該文件中所列用戶不容許使用crontab命令 |
/etc/cron.allow |
該文件中所列用戶容許使用crontab命令 |
/var/spool/cron/ |
全部用戶crontab文件存放的目錄,以用戶名命令 |
用戶所創建的crontab文件中,每一行都表明一項任務,每行的每一個字段表明一項設置,它的格式共分爲六個字段,前五段是時間設定段,第六段是要執行的命令段,格式以下:
1
|
minute hour day month week
command
|
其中:
1
2
3
4
5
6
|
* minute: 表示分鐘,能夠是從0到59之間的任何整數。
* hour:表示小時,能夠是從0到23之間的任何整數。
* day:表示日期,能夠是從1到31之間的任何整數。
* month:表示月份,能夠是從1到12之間的任何整數。
* week:表示星期幾,能夠是從0到7之間的任何整數,這裏的0或7表明星期日。
*
command
:要執行的命令,能夠是系統命令,也能夠是本身編寫的腳本文件。
|
在以上各個字段中,還可使用如下特殊字符:
1
2
3
4
|
* 星號(*):表明全部可能的值,例如month字段若是是星號,則表示在知足其它字段的制約條件後每個月都執行該命令操做。
* 逗號(,):能夠用逗號隔開的值指定一個列表範圍,例如,「1,2,5,7,8,9」
* 中槓(-):能夠用整數之間的中槓表示一個整數範圍,例如「2-6」表示「2,3,4,5,6」
* 正斜線(/):能夠用正斜線指定時間的間隔頻率,例如「0-23
/2
」表示每兩小時執行一次。同時正斜線能夠和星號一塊兒使用,例如*
/10
,若是用在minute字段,表示每十分鐘執行一次。
|
1
|
0 *
/3
* * *
/usr/local/apache2/apachectl
restart
|
#表示每隔3個小時重啓apache服務一次。
1
|
30 3 * * 6
/webdata/bin/backup
.sh
|
#表示每週六的3點30分執行/webdata/bin/backup.sh腳本的操做。
1
|
0 0 1,20 * *
fsck
/dev/sdb8
|
#表示每月的1號和20號檢查/dev/sdb8磁盤設備。
1
|
10 5 *
/5
* *
echo
""
>
/usr/local/apache2/log/access_log
|
#表示每月的5號、10號、15號、20號、25號、30號的5點10分執行清理apache日誌操做。
可用crontab -e命令來編輯,編輯的是/var/spool/cron下對應用戶的cron文件,也能夠直接修改/etc/crontab文件
具體格式以下:
1
2
3
4
5
6
7
8
9
|
Minute Hour Day Month Dayofweek
command
分鐘 小時 天 月 天每星期 命令
每一個字段表明的含義以下:
Minute 每一個小時的第幾分鐘執行該任務
Hour 天天的第幾個小時執行該任務
Day 每個月的第幾天執行該任務
Month 每一年的第幾個月執行該任務
DayOfWeek 每週的第幾天執行該任務
Command 指定要執行的程序
|
在這些字段裏,除了「Command」是每次都必須指定的字段之外,其它字段皆爲可選字段,可視須要決定。對於不指定的字段,要用「*」來填補其位置。
舉例以下:
1
2
3
4
5
|
5 * * * *
ls
指定每小時的第5分鐘執行一次
ls
命令
30 5 * * *
ls
指定天天的 5:30 執行
ls
命令
30 7 8 * *
ls
指定每個月8號的7:30分執行
ls
命令
30 5 8 6 *
ls
指定每一年的6月8日5:30執行
ls
命令
30 6 * * 0
ls
指定每星期日的6:30執行
ls
命令[注:0表示星期天,1表示星期1,
|
以此類推,也能夠用英文來表示,sun表示星期天,mon表示星期一等。
1
2
3
4
|
30 3 10,20 * *
ls
每個月10號及20號的3:30執行
ls
命令[注:「,」用來鏈接多個不連續的時段
25 8-11 * * *
ls
天天8-11點的第25分鐘執行
ls
命令[注:「-」用來鏈接連續的時段
*
/15
* * * *
ls
每15分鐘執行一次
ls
命令 [即每一個小時的第0 15 30 45 60分鐘執行
ls
命令
30 6 *
/10
* *
ls
每月中,每隔10天6:30執行一次
ls
命令[即每個月的一、十一、2一、31日是的6:30執行一次
ls
命令。
|
天天7:50以root 身份執行/etc/cron.daily目錄中的全部可執行文件
1
|
50 7 * * * root run-parts
/etc/cron
.daily [ 注:run-parts參數表示,執行後面目錄中的全部可執行文件。
|
1
2
|
分 小時 日 月 星期 命令
0-59 0-23 1-31 1-12 0-6
command
(取值範圍,0表示週日通常一行對應一個任務)
|
記住幾個特殊符號的含義:
1
2
3
4
|
「*」表明取值範圍內的數字,
「/」表明」每」,
「-」表明從某個數字到某個數字,
「,」分開幾個離散的數字
|
1:
30 30,12 * * * /bin/sh /scripts/andy.sh
在本例中,該定時任務的意思就是天天凌晨3點30分和中午12點30分執行/scripts/andy.sh
2:
30 */6 * * * /bin/sh /scripts/andy.sh
每隔6個小時的半點時刻執行後面的腳本任務
3:
30 8-18/2 * * * /bin/sh /scripts/andy.sh
8點到18點中每隔2小時的30分執行後面的腳本任務(也就是天天的8點半,10點半,12點半,14點半,16點半,18點半)
4:
45 4 1,10,22 * * /application/apache/bin/apachectl graceful
每個月的1,10,22日的凌晨4:45分重啓apache
5:
* 23,00-07/1 * * * /application/apache/bin/apachectl gracefull
上面的例子並不表示晚上23點和早上0-7點之間每隔一小時重啓apache
提示:以上結果是不規範的,也是不對的。
以上的定時任務的第一列爲*,表示每分都執行任務即晚上23點和早上0-7點之間每隔一小時的每分都重啓apache
有時咱們建立了一個crontab,可是這個任務卻沒法自動執行,而手動執行這個任務卻沒有問題,這種狀況通常是因爲在crontab文件中沒有配置環境變量引發的。
在crontab文件中定義多個調度任務時,須要特別注意的一個問題就是環境變量的設置,由於咱們手動執行某個任務時,是在當前shell環境下進行的, 程序固然能找到環境變量,而系統自動執行任務調度時,是不會加載任何環境變量的,所以,就須要在crontab文件中指定任務運行所需的全部環境變量,這樣,系統執行任務調度時就沒有問題了。
每條任務調度執行完畢,系統都會將任務輸出信息經過電子郵件的形式發送給當前系統用戶,這樣日積月累,日誌信息會很是大,可能會影響系統的正常運行,所以,將每條任務進行重定向處理很是重要。
例如,能夠在crontab文件中設置以下形式,忽略日誌輸出:
1
|
0 *
/3
* * *
/usr/local/apache2/apachectl
restart >
/dev/null
2>&1
|
「/dev/null 2>&1」表示先將標準輸出重定向到/dev/null,而後將標準錯誤重定向到標準輸出,因爲標準輸出已經重定向到了/dev/null,所以標準錯誤也會重定向到/dev/null,這樣日誌輸出問題就解決了。
爲crontab中的任務增長本身的日誌,這樣出錯後,比較容易看到緣由。
1
|
0 6 * * * $HOME
/for_crontab/createTomorrowTables
>> $HOME
/for_crontab/mylog
.log 2>&1
|
把錯誤輸出和標準輸出都輸出到mylog.log中。
注意:不要寫成
1
|
0 6 * * * $HOME
/for_crontab/createTomorrowTables
2>&1 >> $HOME
/for_crontab/mylog
.log
|
不然就輸出到標準輸出了
系統級任務調度主要完成系統的一些維護操做,用戶級任務調度主要完成用戶自定義的一些任務,能夠將用戶級任務調度放到系統級任務調度來完成(不建議這麼作),可是反過來卻不行,root用戶的任務調度操做能夠經過「crontab –uroot –e」來設置,也能夠將調度任務直接寫入/etc/crontab文件,須要注意的是,若是要定義一個定時重啓系統的任務,就必須將任務放到/etc /crontab文件,即便在root用戶下建立一個定時重啓系統的任務也是無效的。
(1)增長執行任務頻率調試任務(某些任務不能用於生產環境,沒有測試機會)
代碼發佈:我的開發環境 -- 辦公測試環境 -- IDC機房測試環境 -- IDC正式環境(分組,灰度發佈)
(2)調整系統時間調試任務(不能直接用於生產環境),保持五分鐘
(3)經過腳本日誌輸出調試定時任務
(4)注意一些任務命令帶來的問題
(5)注意環境變量致使的定時任務故障(java環境變量問題: http://oldboy.blog.51cto.com/2561410/1541515)
(6)經過crond定時任務服務日誌調試定時任務(/var/log/cron)
(7)其餘稀奇古怪的問題調試的辦法
1:系統環境變量問題
2:定時任務要用絕對路徑
3:腳本權限問題加/bin/sh
4:時間變量問題用反斜線\%轉義,最好用腳本
5:>/dev/null 2>&1問題(1>/dev/null 2>/dev/null &>/dev/null)
6:定時任務規則以前加註釋
7:使用腳本程序替代命令行定時任務
8:避免沒必要要的程序及命令輸出
9:切到目標目錄的上一級打包目標
10:定時任務腳本中的程序命令儘可能用全路徑(和環境變量的識別有關)
要求:/gin/scripts/poe.sh腳本的功能是打印當天的日期:格式爲:2016-00-10,能夠隨意!
1:定時任務必定儘可能用腳本實現
2:命令行操做成功,而後放到腳本執行成功,最後再配置任務
3:複製操做成功的命令行腳本,再定時任務裏配置。
解答:
步驟1:建立目錄/gin/scripts和編寫poe.sh腳本
1
2
3
4
|
[root@Gin scripts]
# mkdir /gin/scripts -p
[root@Gin scripts]
# echo 'date +%F' >poe.sh
[root@Gin scripts]
# /bin/sh /gin/scripts/poe.sh
2017-01-30
|
步驟2:書寫定時任務
1
2
3
4
5
6
|
[root@Gin scripts]
# echo '#study to linux' >>/var/spool/cron/root
[root@Gin scripts]
# echo '00 09,14 * * 6,0 /bin/sh /gin/scripts/poe.sh >/dev/null 2>&1' >>/var/spool/cron/root
[root@Gin scripts]
# crontab -l
*
/10
* * * *
/usr/sbin/ntpdate
time
.nist.gov >
/dev/null
2>&1
#study to linux
00 09,14 * * 6,0
/bin/sh
/gin/scripts/poe
.sh >
/dev/null
2>&1
|
也能夠輸入crontab -e 而後寫入以下內容保存:
1
2
|
#study to linux
00 09,14 * * 6,0
/bin/sh
/server/scripts/poe
.sh >
/dev/null
2>&1
|
1:爲定時任務規則加必要的註釋
2:定時任務命令或程序最好寫到腳本里執行
3:執行shell腳本任務前加/bin/sh
4:定時任務命令或腳本結尾加 >/dev/null 2>&1
【
結尾爲何要加 >/dev/null 2>&1呢?
C5:sendmail : /var/spool/clientmqueue/ -> 郵件的臨時隊列目錄
系統中開啓了 cron,而cron中執行的程序有輸出內容,輸出內容會以郵件形式發給cron的用戶,而sendmail沒有啓動因此就會在上述目錄產生N個小文件,致使的後果就是把磁盤的inode滿。 -> no space left on device.
C6:postfix /var/spool/postfix/maildrop/ and /var/spool/postfix/maildrop,同上,小文件太多形成inode索引使用完
問題表現和檢查:
1):運行 df -i 查看inode使用是否滿
2):查看/var/spool/postfix/maildrop 是否有很是多的小文件,ls直接卡死等狀況;
解決:
1):cd /var/spool/postfix/maildrop; ls|xrags rm -f;
2):vi /etc/crontab; 將’MAILTO=root’替換成’MAILTO=」」’,而後service crond restart便可。如不行則 crontab -e第一行增長’MAILTO=」」’。
】
5:在指定用戶下執行相關的定時任務
6:生產任務程序不要隨意打印輸出信息 , tar zcf echo 123>a.log
7:定時任務執行的腳本要規範路徑(/server/scripts)
8:配置定時任務規範操做過程
(1)在命令行把具體打包命令調用成功
1
2
3
4
5
6
|
[root@gin etc]
# cd /etc
[root@gin etc]
# tar zcvf /tmp/services_$(date +%F-%H).tar.gz ./services
.
/services
[root@gin etc]
# ll /tmp
-rw-r--r--. 1 root root 641020 Oct 2 2013 services
-rw-r--r-- 1 root root 127304 Oct 7 20:57 services_2016-10-07-20.
tar
.gz
|
(2)寫腳本 /server/scripts/tar.sh
1
2
3
4
5
6
7
|
[root@gin scripts]
# cd /server/scripts/
[root@gin scripts]
# vim tar.sh
cd
/etc
&&
tar
zcf
/tmp/services_
$(
date
+%F-%H).
tar
.gz .
/services
//
測試腳本是否能夠運行成功
[root@gin scripts]
# /bin/sh /server/scripts/tar.sh
[root@gin scripts]
# ll /tmp
-rw-r--r-- 1 root root 127304 Oct 7 21:18 services_2016-10-07-21.
tar
.gz
|
(3)寫入到定時任務中
1
2
3
4
5
6
7
8
9
|
[root@gin scripts]
# crontab -e
//
內容以下:
#tar for /etc/services 2 hours per
00 *
/2
* * *
/bin/sh
/server/scripts/tar
.sh >
/dev/null
2>&1
//
測試腳本
[root@gin scripts]
# /bin/sh -x /server/scripts/tar.sh //-x表示查看命令執行過程
+
cd
/etc
++
date
+%F-%H
+
tar
zcf
/tmp/services_2016-10-07-22
.
tar
.gz .
/services
|
定時任務每次執行,都會產生日誌文件,定時任務的日誌文件目錄:
1
2
3
4
5
6
7
|
[root@gin scripts]
# ll /var/log/cron*
-rw------- 1 root root 25801 Oct 7 21:30
/var/log/cron
-rw-------. 1 root root 5706 Sep 7 16:10
/var/log/cron-20160907
-rw------- 1 root root 8547 Sep 11 11:24
/var/log/cron-20160911
-rw------- 1 root root 38127 Sep 27 10:50
/var/log/cron-20160927
-rw------- 1 root root 19588 Oct 2 11:18
/var/log/cron-20161002
[root@gin scripts]
# cat /var/log/cron //查看日誌
|
1
2
3
|
[root@Gin scripts]
# crontab -e
#print char task by andy for programer A at 2016-10-10
*
/1
* * * *
echo
「andy」 >
/server/log/andy
.log 2>&1
|
四:每隔1分鐘,打印一個+號到andy.log
1
2
|
echo
‘
#print a 「+」 every min by andy 2016-10-10’>>/var/spool/cron/root
echo
‘*
/1
* * * *
echo
+ >>
/tmp/andy
.log’>>
/var/spool/cron/root
|
或者:
1
2
|
[root@Andy andy]
# echo '#!/bin/bash' >echo.sh
[root@Andy andy]
# echo 'echo `date` >>/tmp/andy.log' >>echo.sh
|