1. 程式人生 > >crontab定時任務自動不能執行,手動可以執行的解決辦法-親測解決

crontab定時任務自動不能執行,手動可以執行的解決辦法-親測解決

        最近在做ETL任務排程時,使用系統自帶的任務排程crontab 發現手動執行指令碼可以執行完成,但是自動定時就不能實現,檢查shell指令碼也沒有錯誤。奇怪哪裡導致的問題呢?

        後來在網上查詢和不斷測試,得知和系統的環境變數有關係的。發現指令碼中需要新增必要的環境變數才可以使指令碼自動執行。

     這種情況一般是由於在crontab檔案中沒有配置環境變數引起的。cron從使用者所在的主目錄中使用shell呼叫需要執行的命令。cron為每個shell提供了一個預設的環境,Linux下的定義如下:

  SHELL=/bin/bash

  PATH=/sbin:/bin:/usr/sbin:/usr/bin

  MAILTO=使用者名稱

  HOME=使用者主目錄

  在crontab檔案中定義多個排程任務時,需要特別注意的一個問題就是環境變數的設定,因為我們手動執行某個指令碼時,是在當前shell環境下進行的,程式能找到環境變數;而系統自動執行任務排程時,除了預設的環境,是不會載入任何其他環境變數的。因此就需要在crontab檔案中指定任務執行所需的所有環境變數

  不要假定cron知道所需要的特殊環境,它其實並不知道。所以使用者要保證在shell指令碼中提供所有必要的路徑和環境變數,除了一些自動設定的全域性變數。以下三點需要注意:

  1. 指令碼中涉及檔案路徑時寫絕對路徑;

  2. 指令碼執行要用到環境變數時,通過source命令顯式引入,例如:

  #!/bin/sh

  source/etc/profile

  3. 當手動執行指令碼沒問題,但是crontab不執行時,可以嘗試在crontab中直接引入環境變數解決問題,例如:

  0****./etc/profile;/bin/sh/path/to/myscript.sh

      好了,這個問題就這樣解決了,反正是加上環境變數沒錯的。

================================================================================================

對linux 定時任務的一些附加說明解釋

提供cron服務的程序名為crond,這是Linux下一個用來週期性執行某種任務或處理某些事件的守護程序。當安裝完作業系統後,會自動啟動crond程序,它每分鐘會定期檢查是否有要執行的任務,如果有則自動執行該任務。

  Linux下的任務排程分為兩類,系統任務排程和使用者任務排程。

  ?系統任務排程:系統需要週期性執行的工作,比如寫快取資料到硬碟、日誌清理等。在/etc目錄下有一個crontab檔案,這個就是系統任務排程的配置檔案。

  ?使用者任務排程:使用者要定期執行的工作,比如使用者資料備份、定時郵件提醒等。使用者可以使用crontab命令來定製自己的計劃任務。所有使用者定義的crontab檔案都被儲存在/var/spool/cron目錄中,其檔名與使用者名稱一致。

  1.crontab許可權

  Linux系統使用一對allow/deny檔案組合判斷使用者是否具有執行crontab的許可權。如果使用者名稱出現在/etc/cron.allow檔案中,則該使用者允許執行crontab命令。如果此檔案不存在,那麼如果使用者名稱沒有出現在/etc/cron.deny檔案中,則該使用者允許執行crontab命令。如果只存在cron.deny檔案,並且該檔案是空的,則所有使用者都可以使用crontab命令。如果這兩個檔案都不存在,那麼只有root使用者可以執行crontab命令。allow/deny檔案由每行一個使用者名稱構成。

  2.crontab命令

  通過crontab命令,我們可以在固定間隔的時間點執行指定的系統指令或shell指令碼。時間間隔的單位可以是分鐘、小時、日、月、周及以上的任意組合。crontab命令格式如下:

  crontab[-uuser]file

  crontab[-uuser][-e|-l|-r]

  說明:

  ?-uuser:用來設定某個使用者的crontab服務,此引數一般由root使用者使用。

  ?file:file是命令檔案的名字,表示將file作為crontab的任務列表檔案並載入crontab。如果在命令列中沒有指定這個檔案,crontab命令將接受標準輸入,通常是鍵盤上鍵入的命令,並將它們載入crontab。

  ?-e:編輯某個使用者的crontab檔案內容。如果不指定使用者,則表示編輯當前使用者的crontab檔案。如果檔案不存在,則建立一個。

  ?-l:顯示某個使用者的crontab檔案內容,如果不指定使用者,則表示顯示當前使用者的crontab檔案內容。

  ?-r:從/var/spool/cron目錄中刪除某個使用者的crontab檔案,如果不指定使用者,則預設刪除當前使用者的crontab檔案。

  注意:如果不經意地輸入了不帶任何引數的crontab命令,不要使用Control-d退出,因為這會刪除使用者所對應的crontab檔案中的所有條目。代替的方法是用Control-c退出。

  3.crontab檔案

  使用者所建立的crontab檔案中,每一行都代表一項任務,每行的每個欄位代表一項設定。它的格式共分為六個欄位,前五段是時間設定段,第六段是要執行的命令段,格式如下:

  .----------------分鐘(0-59)

  |.-------------小時(0-23)

  ||.----------日期(1-31)

  |||.-------月份(1-12)

  ||||.----星期(0-6,代表週日到週一)

  |||||

  *****要執行的命令,可以是系統命令,也可以是自己編寫的指令碼檔案。

  在以上各個時間欄位中,還可以使用如下特殊字元:

  ?星號(*):代表所有可能的值,例如“月份”欄位如果是星號,則表示在滿足其他欄位的制約條件後每月都執行該命令操作。

  ?逗號(,):可以用逗號隔開的值指定一個列表範圍,例如,“1,2,5,7,8,9”。

  ?中槓(-):可以用整數之間的中槓表示一個整數範圍,例如“2-6”表示“2,3,4,5,6”。

  ?正斜線(/):可以用正斜線指定時間的間隔頻率,例如“0-23/2”表示每兩小時執行一次。同時正斜線可以和星號一起使用,例如*/10,如果用在“分鐘”欄位,表示每十分鐘執行一次。

  注意,“日期”和“星期”欄位都可以指定哪天執行,如果兩個欄位都設定了,則執行的日期是兩個欄位的並集。

  4.crontab示例

  #每1分鐘執行一次command

  *****command

  #每小時的第3和第15分鐘執行

  3,15****command

  #在上午8點到11點的第3和第15分鐘執行

  3,158-11***command

  #每隔兩天的上午8點到11點的第3和第15分鐘執行

  3,158-11*/2**command

  #每個星期一的上午8點到11點的第3和第15分鐘執行

  3,158-11**1command

  #每晚的21:30執行

  3021***command

  #每月1、10、22日的4:45執行

  4541,10,22**command

  #每週六、週日的1:10執行

  101**6,0command

  #每天18:00至23:00之間每隔30分鐘執行

  0,3018-23***command

  #每星期六的晚上11:00執行

  023**6command

  #每一小時執行一次

  **/1***command

  #晚上11點到早上7點之間,每隔一小時執行一次

  *23-7/1***command

  #每月的4號與每週一到週三的11點執行

  0114*1-3command

  #一月一號的4點執行

  0411*command

  #每小時執行/etc/cron.hourly目錄內的指令碼

  01****rootrun-parts/etc/cron.hourly

  說明:run-parts會遍歷目標資料夾,執行第一層目錄下具有可執行許可權的檔案;