crontab 簡介
crontab 主要用於需要管理週期執行定時任務的場景
crontab 安裝
(有些系統默認已經帶了 crontab,無需安裝的朋友可以直接跳過本節)
安裝:
<code>yum install -y vixie-cron
yum install -y crontabs/<code>
啟動:
<code>systemctl start crond.service/<code>
重啟:
systemctl restart crond.service
設置開機啟動:
<code>systemctl enable crondservice/<code>
命令格式
crontab 主要有以下幾種命令格式
<code>crontab [-u user] file
crontab [-u user] [-l | -r | -e] [-i] [-s]
crontab -n [ hostname ]
crontab -c/<code>
我們發現crontab 的命令還挺多的,我們先從最常用的開始:
crontab -e
這個命令用於編輯定時任務列表,當我們輸入完命令,按下回車鍵之後,它會使用默認編輯器(通常是vi/vim)打開一個文件,裡面的內容可能是這樣子的:
這很可能是你看到的,在設置任何定時任務之前,這裡是看不到任何內容的,如果你已經設置了內容的話,那麼看到的可能是這樣的
這是我提前設置好的定時任務,我們暫時不解釋這個配置的功能,但從這裡可以知道,通過 crontab -e 我們可以編輯定時任務。
如果我們什麼都不做,直接退出編輯器會看到以下提示:
如果我們修改了這個文件,比如增加了一個任務
保存退出之後,我們可以看到成功的提示:
如果說,我們的配置有誤,那麼系統就會提示我們, 重新編輯,你可以輸入 y 重新編輯 或者 n 放棄剛剛的配置的內容
crontab -l
這個命令可以列出當前的定時任務內容, 這與我們使用 crontab -e 看到的內容一樣,不同的是 crontab -e 可以編輯,而這裡只能查看
crontab -r
這個命令用於刪除任務列表裡面的內容(在刪除之前我們先做一個備份)
通過上面的示例可以看出,執行完 crontab -r 之後,我們的任務列表被清空了
crontab file
這個命令用於將保存在某個文件中的任務列表中的內容覆蓋到我們的任務列表中,我們剛剛在刪除任務列表前做了備份
現在來看一下,使用命令能否將任務列表還原回去
可以看到,通過 crontab file 命令,我們將剛剛備份的文件內容恢復到任務列表當中了。
有兩點需要注意:
- 這個命令的操作很粗暴,會用指定文件的內容直接覆蓋任務列表,使用前一定要想清楚,最好在操作前進行備份
- 用於覆蓋的文件內容必須是合法的內容,如果語法有誤,內容將不會更新,且會得到下圖所示的錯誤提示
crontab -ri
這個命令用於刪除任務列表裡面的內容,但會在刪除之前讓你確認是否刪除
你可以輸入 y 確認刪除,也可以輸入 n 取消這次操作
crontab -u user_name
這裡我們補充一點,Linux 中的每個用戶都可以有自己的定時任務,他們設置的任務被保存在 /var/spool/cron/ 目錄下的同名文件中
這個命令跟 -i 一樣,需要與其它命令配合使用
<code>crontab [-u user] file
crontab [-u user] [-l | -r | -e] [-i] [-s]/<code>
不使用 -u 時默認的就是當前用戶,如果你要配置其它用戶的任務列表
就可以使用這個命令
<code>crontab -u user -e/<code>
當然,使用這個命令的前提是要有對應文件的操作權限,大多數情況下,這個命令都是 root 在用。
需要注意的是,根據文檔提示,如果你從一個普通用戶 su 到其它用戶,在進行crontab 命令時,就一定要加上 -u 選項。但我實驗發現, su 到其它用戶之後,再進行 crontab 操作,默認使用的 su 之後的用戶。
任務列表的語法
接這部分是最重要的任務規則配置環節
上面這個截圖是 /etc/crontab 文件的內容,使用 crontab -e 編輯的語法也這個基本一樣,差別只有 user-name 一項。
使用 crontab -e 無需指定用戶名稱,因為這個命令就是使用用戶自己的身份來執行的。
補充: /etc/crontab 中的內容只能由 root 來設置,一般用於設置系統級的週期任務
從上面的圖裡面可以知道,週期任務的配置語法由兩部分組成(使用 contab -e 時忽略 user-name)
- 時間規則
- 要執行命令或者腳本
時間規則
前面5個 * 分別代表 分、時、日、月、周
- 第一個 * 代表每一分鐘,也可以是 0-59 區間中的數字
- 第二個 * 代表每個小時,也可以是 0-23 區間中的數字
- 第三個 * 代表一個月中的每一天,也可以是 1-31 區間中的數字
- 第四個 * 代表一年中的每個月, 也可以是 1-13 區間中的數字,或者使用英文 jan,feb,mar,apr... 等來表示
- 第五個 * 代表一週中的每一天, 也可以是 0-6 區間中的數字(星期天使用 0 或者 7 表示),也可以使用 sum,mon,tue,wed,thu,fri,sat 來表示
除了上面的配置方式之外,crontab 還支持更靈活的配置方式:
- * 每個時間點,如在分鐘單位,則表示每分鐘執行一次,其它時間點同理
- , 用於連接多個時間點,如 1,3,5 指定1,3,5這三個時間點
- - 用於確定時間區間,如 2-6 等價於 2,3,4,5,6
- / 用於每隔一個時間段執行一次,如在分鐘位置設置 */2 表示每兩分鐘執行一次
注意,上述符號中的非標準符號不一定能在你的機器上正常運行,在使用前一定要先進行測試
命令
可以是shell命令或者執行某個已經寫好的腳本
實例
以下舉幾個實例的例子
<code># 表示每分鐘執行一次
* * * * * cmd
# 每個小時的0分和30分執行各執行一次
0,30 * * * * * cmd
# 每天的2點到5點每個小時的整點執行
0 2-5 * * * cmd
# 每年的 1月1日0點執行
0 0 1 1 * cmd
# 每天的12點到18點每隔3小時執行一次
0 12-18/3 * * * cmd
# 每個月最後的天的22點整執行(非標準語法,要先進行測試再投入生產環境)
0 22 L * * cmd/<code>
cron.allow 與 cron.deny
執行cron任務的權限是可以通過 /etc/cron.allow 和 /etc/cron.deny 兩個文件進行配置。
- cron.allow 用於配置哪些用戶可以使用 crontab
- cron.deny 用於配置哪些用戶禁止使用 crontab
這兩個文件的內容為每一行一個用戶名,或者為空
- 如果 cron.allow 文件存在的話,需要限權的用戶名必須在這個文件裡面
- 如果 cron.deny 文件存在的話,需要權限的用戶不能出現在這個文件裡面
- 如果兩個文件都不存在的話,則只有 root 有權限使用 crontab
當上述兩個文件都不存在時,一個普通使用執行 crontab 命令會得到以下錯誤
環境變量
在實際使用過程中, 我們都會編輯好一個 .sh 文件,設置好權限(一般是增加執行權限 chmod +x task.sh )
測試成功之後,興高采烈地把它添加到 crontab 的任務列表裡面,結果遲遲沒有得到預期結果。
我之前碰到這樣的情況,直接執行腳本沒問題,但使用 crontab 執行卻報錯,查看日誌發現是環境變量的問題。
解決的辦法很簡單,只要在腳本內提前導入環境變量即可:
執行結果保存
設置完任務列表之後,我們最關心的主是任務的執行情況
可以在配置任務的時候,在最後加入以下將執行過程中輸出的內容保存到自己想要的地方。
<code>*/5 * * * * cmd > /var/log/cron_task.log 2>&1 &/<code>
語法解析詳見 crontab 腳本錯誤日誌和正確的輸出寫入到文件
日誌文件
我們可以查看 /var/log/cron 文件的內容來查看服務器執行了哪些任務
(我的是CentOS, 如果是Ubuntu可以到 /var/log/cron.log 查看)
待補充
以下幾點是我看了文檔之後還不太明白的幾點(主要還是英文水平還不夠。。)
- crontab [-u user] -s
- crontab -n [hostname]
- crontab -c
- /etc/crontab 和 /etc/cron.d 文件內也可以設置任務列表,具體的使用場景我還沒有接觸過
以上所有內容是結合自己的實踐與官方文檔加上網友們的文章寫成,還有很多自己不理解的,希望看到的朋友如果有知道的也評論告訴我哦,謝謝啦
閱讀更多 sandag 的文章