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會遍歷目標資料夾,執行第一層目錄下具有可執行許可權的檔案;