Linux 定時任務

the-ruffian發表於2022-03-30

參考文章:

Linux下的crontab定時執行任務命令詳解
Linux中的定時任務crontab

 

  • 在LINUX中,週期執行的任務一般由cron這個守護程式來處理[ps -ef|grep cron]。cron讀取一個或多個配置檔案,這些配置檔案中包含了命令列及其呼叫時間。
  • cron的配置檔案稱為“crontab”,是“cron table”的簡寫。

 

一. cron服務

cron是一個linux下 的定時執行工具,可以在無需人工干預的情況下執行作業。
service crond start    //啟動服務
service crond stop     //關閉服務
service crond restart  //重啟服務
service crond reload   //重新載入配置
service crond status   //檢視服務狀態 

 

二. cron在3個地方查詢配置檔案

①/var/spool/cron/ 這個目錄下存放的是每個使用者包括root的crontab任務,每個任務以建立者的名字命名,比如tom建的crontab任務對應的檔案就是/var/spool/cron/tom。一般一個使用者最多隻有一個crontab檔案。

②/etc/crontab 這個檔案負責安排由系統管理員制定的維護系統以及其他任務的crontab

③/etc/cron.d/ 這個目錄用來存放任何要執行的crontab檔案或指令碼。

 

三. 許可權

crontab許可權問題到/var/adm/cron/下一看,檔案cron.allow和cron.deny是否存在
用法如下: 
1、如果兩個檔案都不存在,則只有root使用者才能使用crontab命令。 
2、如果cron.allow存在但cron.deny不存在,則只有列在cron.allow檔案裡的使用者才能使用crontab命令,如果root使用者也不在裡面,則root使用者也不能使用crontab。 
3、如果cron.allow不存在, cron.deny存在,則只有列在cron.deny檔案裡面的使用者不能使用crontab命令,其它使用者都能使用。 
4、如果兩個檔案都存在,則列在cron.allow檔案中而且沒有列在cron.deny中的使用者可以使用crontab,如果兩個檔案中都有同一個使用者,
以cron.allow檔案裡面是否有該使用者為準,如果cron.allow中有該使用者,則可以使用crontab命令。

 

四. cron的具體使用

  • 使用命令crontab -e即可編輯crontab,在裡面新增需要的定時任務。使用者的定時任務檔案為 /var/spool/cron/使用者名稱 ,crontab -e命令將相當於vim /var/spool/cron/使用者名稱。

 

1. 如何寫crontab

  • crontab中每一行代表一個任務,每個任務由週期和任務名組成。如下形式   

59 23 10 5 2014 /home/root/tesh.sh

#分 時 日 月 年 |<-------命令串------->|

 

        表示2014年5月10日23點59分,執行/home/root下的tesh.sh指令碼。

  • 時間週期中可以使用一些輔助字元,如:
    *    表示任何時刻都可以
    ,  若有多個時刻,用逗號分隔
    -     表示一個時刻到另一時刻之間的時間段
    /n   表示每過n個時間單位
  • 比如,*/10 3-6 10,11 * * /home/root/tesh.sh 就表示 每年每月的10號和11號,3點到6點之間,每過10分鐘執行一次tesh.sh

  • Cron表示式是一個字串,字串以4或5個空格隔開,分為5或7個域,每一個域代表一個含義,Cron有如下兩種語法格式: 
    Minutes Hours DayofMonth Month DayofWeek Year或 
    Minutes Hours DayofMonth Month DayofWeek

    每一個域可出現的字元如下: 
    Minutes:可出現", - * /"四個字元,有效範圍為0-59的整數 
    Hours:可出現", - * /"四個字元,有效範圍為0-23的整數 
    DayofMonth:可出現", - * / ? L W C"八個字元,有效範圍為1-31的整數 
    Month:可出現", - * /"四個字元,有效範圍為1-12的整數或JAN-DEc 
    DayofWeek:可出現", - * / ? L C #"四個字元,有效範圍為1-7的整數或SUN-SAT兩個範圍。1表示星期天,2表示星期一, 依次類推 
    Year:可出現", - * /"四個字元,有效範圍為1970-2099年

 

  • 每一個域都使用數字,但還可以出現如下特殊字元,它們的含義是: 
    ①*:表示匹配該域的任意值,假如在Minutes域使用*, 即表示每分鐘都會觸發事件。
    ②?:只能用在DayofMonth和DayofWeek兩個域。它也匹配域的任意值,但實際不會。因為DayofMonth和DayofWeek會相互影響。例如想在每月的20日觸發排程,不管20日到底是星期幾,則只能使用如下寫法: 13 13 15 20 * ?, 其中最後一位只能用?,而不能使用*,如果使用*表示不管星期幾都會觸發,實際上並不是這樣。 
    ③-:表示範圍,例如在Minutes域使用5-20,表示從5分到20分鐘每分鐘觸發一次 
    ④/:表示起始時間開始觸發,然後每隔固定時間觸發一次,例如在Minutes域使用5/20,則意味著5分鐘觸發一次,而25,45等分別觸發一次. 
    ⑤,:表示列出列舉值值。例如:在Minutes域使用5,20,則意味著在5和20分每分鐘觸發一次。 
    ⑥L:表示最後,只能出現在DayofWeek和DayofMonth域,如果在DayofWeek域使用5L,意味著在最後的一個星期四觸發。 
    ⑦W:表示有效工作日(週一到週五),只能出現在DayofMonth域,系統將在離指定日期的最近的有效工作日觸發事件。例如:在 DayofMonth使用5W,如果5日是星期六,則將在最近的工作日:星期五,即4日觸發。如果5日是星期天,則在6日(週一)觸發;如果5日在星期一到星期五中的一天,則就在5日觸發。另外一點,W的最近尋找不會跨過月份 
    ⑧LW:這兩個字元可以連用,表示在某個月最後一個工作日,即最後一個星期五。 
    ⑨#:用於確定每個月第幾個星期幾,只能出現在DayofMonth域。例如在4#2,表示某月的第二個星期三。

 

2. crontab註釋

  • 在crontab中,#代表了註釋,註釋的存在,能夠簡化crontab的一些複雜操作。

 

  • 比如,如果有一個任務test.sh,每天都需要執行,每過10分鐘執行一次,我們可以寫成 */10 * * * * tesh.sh。現在有新要求,每天1點到1點10分不能執行,其餘時間照舊。

    一種寫法就是:將它拆成多條crontab,比如每天2點到0點執行,每天0點到1點執行,每天1點10分到2點執行。三條語句。這種方法的問題就是,如果再來新的要求呢,比如在此基礎之上,每天8點到8點10分不能執行,這又怎麼處理,寫更多的crontab任務嗎?

    另一種比較好的解決方案是:寫一個run.sh指令碼,每10分鐘執行一次,首先判斷當前時間是否是在1點到1點10分之間,如果不是,就執行tesh.sh,如果是,可以sleep10分鐘。

    第三種非常好的方案就是利用註釋。我們可以在1點時,將tesh.sh任務給註釋掉,在1點10分,將tesh.sh任務的註釋消除。要實現這種想法,需要使用sed命令。可以在crontab裡面這樣寫:

#每隔10分鐘執行一次
*/10 * * * * tesh.sh
 
#每天1點鐘,將命令註釋掉
0 1 * * * sudo sed -i 's\%\(\*\/10 \* \* \* \* tesh.sh\)\%#\1\%' /var/spool/cron/使用者名稱
 
#每天1點零10分,將被註釋的命令恢復
10 1 * * * sudo sed -i 's\%\(^##*\)\(\*\/10 \* \* \* \* tesh.sh\)\%\2\%' /var/spool/cron/使用者名稱
 

  • sed -i表示直接修改檔案內容,之後的動作必須用單引號括上,單引號之後的是檔案。單引號內部s表示替換,s之後的%是分隔符,代替預設的/分隔符,括弧表示將括號裡面的內容儲存下來,標記為1,#表示把註釋擴充套件到下一個換行符以前,\1表示選取括號中的內容。
  • 這裡出現了眾多的反斜槓,都是用來做轉義的,否則會被解析。
  • %前面的反斜槓是用來轉義crontab的,crontab中會將%解析成換行符。括弧和*前的反斜槓是因為sed會解析它們。
  • 如果不是在crontab中,這個命令可以寫成 sed -i 's%\*\/10\*\*\*\*tesh.sh\*\/10\*\*\*\*tesh.sh%#\1%'  file

 

3. crontab的除錯方式

  • 如果crontab不執行,我們可以使用 sudo vim /var/spool/mail/使用者名稱檢視系統發給使用者的mail,可以通過時間點,來找出執行失敗的原因。

相關文章