『學了就忘』Linux系統定時任務 — 88、迴圈執行定時任務

繁華似錦Fighting發表於2021-12-22

需使用crontab命令。

crontab命令可以迴圈執行定時任務。比如每天的凌晨2點都執行一次某個任務。

cron服務是Linux系統自帶的守護程式(daemon),用來重複執行某些被設定好了確定的執行時間的任務,這些任務可以是每個月執行、每週執行、每天執行,甚至是每一分鐘執行。

在Linxu系統中,有三種用於任務排程的工具

  • at命令呼叫atd服務。
  • crontab命令呼叫cron(crond)服務。
  • anacron工具。

1、crond服務管理與訪問控制

crontab命令是需要crond服務支援的,crond服務同樣是獨立的服務,所以啟動和自啟動方法如下:

# 重啟動crond服務
[root@localhost ~]# service crond restart
停止 crond:                                [確定]
正在啟動 crond:                             [確定]


# 設定crond服務為開機自啟動
[root@localhost ~]# chkconfig crond on

提示:只要你的Linux系統是安裝的,哪怕是最小化安裝,at服務和cron服務預設都是啟動的。

image

2、crontab命令的訪問控制

crond服務預設是自啟動的,如果伺服器上有迴圈執行的系統定時任務,就不要關閉crond服務了。
crontab命令和at命令類似,也是通過/etc/cron.allow/etc/cron.deny檔案來限制某些使用者是否可以使用crontab命令的,而且原則也非常相似:

  1. 當系統中有/etc/cron.allow檔案時,只有寫入此檔案的使用者可以使用crontab命令,沒有寫入的使用者不能使用crontab 命令。同樣如果有此檔案,/etc/cron.deny檔案會被忽略,/etc/cron.allow檔案的優先順序更高。
  2. 當系統中只有/etc/cron.deny檔案時,則寫入此檔案的使用者不能使用crontab命令,沒有寫入檔案的使用者可以使用crontab命令。

crontab命令規則基本和at命令的規則一直,同樣/etc/cron.allow檔案的優先順序比/etc/cron.deny檔案的優先順序高,Linux 中預設只有/etc/cron.deny檔案。

3、使用者級別的crontab命令

(1)crontab命令介紹

cron服務提供crontab命令來設定cron服務的,

也就是使用crontab命令的方式實現cron定時任務。

每個使用者都可以實現自己的crontab定時任務,只要是使用使用者身份執行crontab -e命令即可,當然這個使用者不能加入/etc/cron.deny檔案中。

也就是說這種方式只能是,哪個使用者定義的crontab定時任務,就由哪個使用者來執行。

crontab命令格式如下:

[root@localhost ~]# crontab [選項]

選項:
  -e:編輯crontab定時任務
  -l:查詢crontab任務
  -r:刪除當前使用者所有的crontab任務,如果有多個任務,只想刪除一個,可以用“crontab -e”
  -u使用者名稱:修改或刪除其他使用者的crontab任務。只有root可用。

示例:

# 進入crontab編輯介面。
# 會開啟一個空的文字檔案,是一個vim編輯介面。
# 在vim中編寫你的工作。
[root@localhost ~]# crontab -e

# 編輯的內容
*****執行的任務

提示:

任務可以是單一的執行命令,單一的命令所能完成的工作是比較少的,一般在工作中都是使用執行指令碼。

內容含義說明:

專案 含義 範圍
第一個”*“ 一小時當中的第幾分鐘 0-59
第二個”*“ 一天當中的第幾小時 0-23
第三個”*“ 一個月當中的第幾天 1-31
第四個”*“ 一年當中的第幾月 1-12
第五個”*“ 一週當中的星期幾 0-7(0和7都代表星期日)

時間的表示式中,還有一些特殊符號:

特殊符號 含義
* 代表任何時間。比如第一個“*”就代表一小時中每分鐘都執行一次的意思。
, 代表不連續的時間。比如0 8,12,16 * * * 所要執行的命令,就代表在每天的8點0分,12點0分,16點0分都執行一次命令。
- 代表連續的時間範圍。比如0 5 * * 1-6 所要執行的命令,代表在週一到週六的凌晨5點0分執行命令。
*/10 代表每隔多久執行一次。比如*/10 * * * * 所要執行的命令,代表每隔10分鐘就執行一遍命令。

時間表示式示例:

時間 含義
10 * * * * 所要執行的命令 每小時的第10分鐘執行一次命令
45 22 * * * 所要執行的命令 在22點45分執行命令
0 17 * * 1 所要執行的命令 每週1的17點0分執行命令
0 5 1,15 * * 所要執行的命令 每月1日和15日的凌晨5點0分執行命令
40 4 * * 1-5 所要執行的命令 每週一到週五的凌晨4點40分執行命令
*/10 4 * * * 所要執行的命令 每天的凌晨4點,每隔10分鐘執行一次命令
0 0 1,15 * 1 所要執行的命令 每月1日和15日,每週1的0點0分都會執行命令。
日和星期不是並且的關係,是或者的關係。

注意:星期幾和幾號最好不要同時出現,因為他們定義的都是天,非常容易讓管理員混亂。

在舉一個特例:

0 6 31 * * 所要執行的命令,不一定每個月都有31日,在沒有31日的月份就不執行。在做定時任務的時候,最後不要選這麼極端的時間。

crontab命令定時任務示例:

  • 讓系統每隔1分鐘,就向/tmp/test檔案中寫入一行“12345”,驗證一下系統定時任務是否會執行。
    [root@localhost ~]# crontab -e
    
    # 進入vim編輯介面
    * * * * * /bin/echo "12345" >> /tmp/test
    
  • 系統在每週二的凌晨5點05分重啟一次
    [root@localhost ~]# crontab -e
    
    # 進入vim編輯介面
    5 5 * * 2 /sbin/shutdown -r now
    

    提示:不建議用定時任務執行伺服器重啟,有可能出現伺服器沒有重新啟動的情況。伺服器的重啟操作最好還是需要管理員參與。

  • 在每月的1號,10號,15號的凌晨3點30分都定時執行日誌備份指令碼autobak.sh
    [root@localhost ~]# crontab -e
    
    # 進入vim編輯介面
    30 3 1,10,15 * * /root/sh/autobak.sh
    

    這個操作常用。

(2)檢視crontab任務

檢視root使用者的crontab任務。

[root@localhost ~]# crontab -l
* * * * * /bin/echo "12345" >> /tmp/test

(3)刪除crontab任務

刪除root使用者所有的定時任務。

[root@localhost ~]# crontab -r

提示:如果只想刪除某一個定時任務,需要進入crontab -e編輯模式手工刪除。

4、crontab命令的注意事項

在書寫crontab定時任務時,需要注意幾個注意事項,這裡我們再強調下:

  1. 六個選項都不能為空,必須填寫,如果不確定使用*代表任意時間。
  2. crontab定時任務,最小有效時間是分鐘,最大有效時間是月。像2020年某時執行,3點30分30秒這樣的時間都不能識別。
  3. 在定義時間時,日期和星期最好不要在一條定時任務中出現,因為它們都是以天作為單位,非常容易讓管理員混亂。
  4. 在定時任務中,不管是直接寫命令,還是在指令碼中寫命令,最好都是用絕對路徑。有時相對路徑的命令會報錯。

5、系統的crontab設定

(1)/etc/crontab配置檔案說明

crontab -e是每個使用者執行的命令,也就是說不同的使用者身份可以執行自己的定時任務。可是有些定時任務需要系統執行,這時我們就需要編輯/etc/crontab這個配置檔案了。

並不是說寫入/etc/crontab配置檔案中的定時任務執行時,不需要使用者身份,而是crontab -e命令定義定時任務時,預設使用者身份是當前登入使用者。而修改/etc/crontab配置檔案時,定時任務的執行者的身份,是可以手工指定的。

這樣定時任務的執行會更加靈活,修改起來也更加方便。

我們來檢視一下/etc/crontab配置檔案:

[root@localhost ~]# vim /etc/crontab 

# /etc/crontab 配置檔案內容
# 1.標識使用哪種shell
SHELL=/bin/bash
# 2.指定PATH環境變數,crontab是使用自己的PATH,
# 而不是用系統預設的,所以在定時任務中出現的命令最好使用絕對路徑。
PATH=/sbin:/bin:/usr/sbin:/usr/bin
# 3.如果有報錯輸出,或命令結果有輸出,會向root發資訊
MAILTO=root
# 4.標識主目錄
HOME=/

# 5.提示大家可以去“man 4 crontabs"檢視幫助
# For details see man 4 crontabs

# 6.列出檔案格式,並加入了註釋
# 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 be executed
# 分 時  日 月 周 執行者身份     命令

CentOS 5.x/etc/crontab檔案的內容大概是這個樣子:

[root@localhost ~]# vim /etc/crontab 

# /etc/crontab 配置檔案內容
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

說明:

  • CentOS 5.x版本中,/etc/crontab檔案會使用run-parts指令碼執行/etc/cron.{daily,weekly,monthly}目錄中的所有檔案。這個run-parts其實是一個shell指令碼,儲存在/usr/bin/run-parts,它的作用就是把其後面跟隨的目錄中的所有可執行檔案依次執行。
    (意思是說在daily,weekly,monthly這些目錄裡存放指令碼,並按賦予run-parts指令碼的定時時間來執行目錄中的所有指令碼)
    (在CentOS 6.x版本中也存在)
  • 02 4 * * * root run-parts /etc/cron.daily為例:
    如果我們想讓某個指令碼在每天都執行一次,可以不用手工去寫定時任務,而只需要給run-parts指令碼賦予執行許可權,並把它放入/etc/cron.daily/目錄中,這樣這個指令碼就會在每天的凌晨4點02分執行了。
  • 我們在來看看/etc/cron.{daily,weekly,monthly}目錄
    進入到etc目錄中檢視上面這幾個目錄,如下圖所示:
    image
    我們可以看到daily,weekly,monthly是三個目錄,裡邊存放著一些可執行指令碼。
    這裡我們就明白了,當按照定時表示式執行一個run-parts指令碼的時候,run-parts指令碼會把跟在他後邊的目錄中的指令碼都執行一次,從而完成定時任務。

CentOS 6.x版本中crontab命令是如何執行定時任務的呢?

我們看到/etc/crontab中有一句提示,讓我們man 4 crontabs來檢視幫助。在這個幫助中,明確寫明瞭“在舊版本的crontab配置檔案中,是通過run-parts指令碼來呼叫/etc/cron.{daily,weekly,monthly}目錄中的指令碼檔案,定時執行這些目錄中的指令碼。在當前系統中,為了避免cronanacron之間產生衝突,只要anacron已經安裝,就使用anacron來執行這些目錄中的指令碼。”

對於anacron工具的用法,我們下一篇文章來介紹。

(2)通過配置檔案的方式設定定時任務

其實對我們使用者來講,並不需要知道這個定時任務到底是由哪個程式呼叫的。我們需要知道的事情是如何使用系統的crontab設定。

這個新老版本的CentOS沒有區別,配置方法都有兩種:

1)方式一

第一種方法就是上面說過的,把你需要定時執行的工作寫成指令碼程式,並賦予執行許可權,然後直接把這個指令碼複製到/etc/cron.{daily,weekly,monthly}目錄中的任意一個。比如我需要讓某個指令碼每週執行,那麼就把這個指令碼複製到/etc/cron.weekly/目錄中。這樣這個指令碼就會每週執行一次,具體的執行時間要參考anacron的配置。

2)方式二

第二種方法就是修改/etc/crontab這個配置檔案,自己加入自己的定時任務,不過需要注意指定指令碼的執行者身份。

例如:

[root@localhost ~]# vim /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 be executed

# 如下編輯定時任務
# 說明:
#	讓系統每分鐘都執行一次/root/cron目錄中的指令碼,指令碼執行者是root使用者。
#	雖然在Centos 6.x中,不是直接通過此配置檔案呼叫/etc/cron.{daily,weekly,monthly}這些目錄,
#	但是run-parts指令碼還是可以使用的。所以我完全可以參照CentOS 5.x的方法來寫定時任務。
#	使用run-parts指令碼呼叫並執行/root/cron/目錄中所有的可執行檔案
* * * * * root run-parts /root/cron/
#	/root/cron/是自己指定的目錄,也可以是預設的/etc/cron.{daily,weekly,monthly}這些目錄

# 儲存退出

# 建立/root/cron目錄
[root@localhost ~]# mkdir /root/cron

# 在/root/cron/目錄中編輯一個hello.sh指令碼
# 向hello.log檔案中寫入“hello”
[root@localhost ~]# vim /root/cron/hello.sh
#!/bin/bash 
echo "hello" >> /root/cron/hello.log

# 儲存退出

# 給hello.sh指令碼賦予執行許可權。
[root@localhost ~]# chmod 755 hello.sh

# 注:因為hello.sh指令碼放入了/root/cron/目錄,所以會每分鐘執行一次。

只要儲存/etc/crontab檔案,這個定時任務就可以執行了,當然要確定crond服務是執行的。

這兩種方法都是可以使用的,具體看個人的習慣吧!不過要想修改/etc/crontab檔案,當然我要是root使用者才可以,普通不能修改,只能使用使用者身份的crontab命令。

相關文章