在 Linux 系統管理中,自動化是提升效率的關鍵。Cron 是 Unix/Linux 系統中最常用的排程工具,能夠讓系統管理員在指定的時間自動執行腳本或命令。本文將深入介紹如何在 Ubuntu 22.04 中使用 Cron 來實現任務自動化。
Cron 簡介
Cron 是一個在背景執行的守護程序(daemon),它會根據預先設定的時間表自動執行指定的任務。這些排程任務被稱為「cron jobs」,而定義這些任務的檔案則稱為「crontab」(cron table 的縮寫)。
Cron 的主要特點
- 時間精確:可以精確到分鐘級別的排程
- 靈活性高:支援各種時間組合設定
- 系統整合:與 Linux 系統深度整合
- 使用者隔離:每個使用者可以有自己的 crontab
檢查 Cron 服務狀態
在 Ubuntu 22.04 中,可以使用以下命令檢查 cron 服務是否正在執行:
1
| sudo systemctl status cron
|
如果服務未啟動,可以使用以下命令啟動:
1
2
| sudo systemctl start cron
sudo systemctl enable cron
|
Crontab 語法
Crontab 的語法由六個欄位組成,前五個欄位定義執行時間,最後一個欄位是要執行的命令:
1
2
3
4
5
6
7
8
| ┌───────────── 分鐘 (0 - 59)
│ ┌───────────── 小時 (0 - 23)
│ │ ┌───────────── 日期 (1 - 31)
│ │ │ ┌───────────── 月份 (1 - 12)
│ │ │ │ ┌───────────── 星期幾 (0 - 7,0 和 7 都代表星期日)
│ │ │ │ │
│ │ │ │ │
* * * * * 要執行的命令
|
特殊符號說明
| 符號 | 說明 | 範例 |
|---|
* | 任意值 | * * * * * 每分鐘執行 |
, | 列舉多個值 | 0,30 * * * * 每小時的 0 分和 30 分執行 |
- | 範圍 | 0 9-17 * * * 每天 9 點到 17 點的整點執行 |
/ | 間隔 | */15 * * * * 每 15 分鐘執行一次 |
基本操作命令
1
2
3
4
5
6
7
8
9
10
11
| # 編輯當前使用者的 crontab
crontab -e
# 列出當前使用者的 crontab
crontab -l
# 刪除當前使用者的 crontab
crontab -r
# 編輯特定使用者的 crontab(需要 root 權限)
sudo crontab -u username -e
|
常見排程範例
以下是一些實用的 cron 排程範例:
基本時間排程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # 每分鐘執行一次
* * * * * /path/to/script.sh
# 每小時執行一次(每小時的第 0 分鐘)
0 * * * * /path/to/script.sh
# 每天凌晨 3 點執行
0 3 * * * /path/to/script.sh
# 每週一凌晨 5 點執行
0 5 * * 1 /path/to/script.sh
# 每月 1 號凌晨 4 點執行
0 4 1 * * /path/to/script.sh
|
進階時間排程
1
2
3
4
5
6
7
8
9
10
11
| # 每 15 分鐘執行一次
*/15 * * * * /path/to/script.sh
# 工作日(週一到週五)每天早上 9 點執行
0 9 * * 1-5 /path/to/script.sh
# 每天凌晨 2 點和 14 點執行
0 2,14 * * * /path/to/script.sh
# 每季度第一天凌晨執行
0 0 1 1,4,7,10 * /path/to/script.sh
|
實際應用範例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # 每天備份資料庫
0 2 * * * /usr/local/bin/backup-database.sh >> /var/log/backup.log 2>&1
# 每小時同步檔案
0 * * * * rsync -avz /source/ /destination/
# 每天清理暫存檔案
0 4 * * * find /tmp -type f -mtime +7 -delete
# 每週日凌晨更新系統
0 3 * * 0 apt update && apt upgrade -y
# 每 5 分鐘檢查服務狀態
*/5 * * * * /usr/local/bin/check-service.sh
|
特殊時間字串
Cron 也支援一些預定義的特殊時間字串:
1
2
3
4
5
6
7
8
| @reboot # 系統啟動時執行
@yearly # 每年執行一次(等同於 0 0 1 1 *)
@annually # 與 @yearly 相同
@monthly # 每月執行一次(等同於 0 0 1 * *)
@weekly # 每週執行一次(等同於 0 0 * * 0)
@daily # 每天執行一次(等同於 0 0 * * *)
@midnight # 與 @daily 相同
@hourly # 每小時執行一次(等同於 0 * * * *)
|
範例:
1
2
3
4
5
| # 系統啟動時執行初始化腳本
@reboot /usr/local/bin/init-script.sh
# 每天執行日誌輪替
@daily /usr/sbin/logrotate /etc/logrotate.conf
|
系統級 Cron
除了使用者級別的 crontab,Ubuntu 22.04 還提供了系統級的 cron 設定。
系統 Crontab 檔案
系統級的 crontab 位於 /etc/crontab,其語法與使用者 crontab 略有不同,需要額外指定執行使用者:
1
2
3
4
5
| # /etc/crontab 格式
分 時 日 月 週 使用者 命令
# 範例
0 3 * * * root /usr/local/bin/system-backup.sh
|
Cron 目錄
Ubuntu 22.04 提供了預設的 cron 目錄,方便管理不同週期的任務:
| 目錄 | 執行週期 |
|---|
/etc/cron.hourly/ | 每小時執行 |
/etc/cron.daily/ | 每天執行 |
/etc/cron.weekly/ | 每週執行 |
/etc/cron.monthly/ | 每月執行 |
將腳本放入這些目錄即可自動按對應週期執行:
1
2
3
4
5
| # 建立每日備份腳本
sudo nano /etc/cron.daily/backup
# 確保腳本有執行權限
sudo chmod +x /etc/cron.daily/backup
|
/etc/cron.d/ 目錄
/etc/cron.d/ 目錄用於存放獨立的 cron 設定檔,適合套件或應用程式使用:
1
2
3
4
5
6
7
8
| # 建立自訂 cron 設定
sudo nano /etc/cron.d/my-custom-job
# 檔案內容範例
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
0 */4 * * * root /opt/myapp/scripts/cleanup.sh
|
日誌與除錯
當 cron 任務無法正常執行時,日誌和除錯技巧非常重要。
查看 Cron 日誌
在 Ubuntu 22.04 中,cron 日誌預設記錄在系統日誌中:
1
2
3
4
5
6
7
8
9
10
11
| # 使用 journalctl 查看 cron 日誌
sudo journalctl -u cron
# 查看最近的 cron 日誌
sudo journalctl -u cron --since today
# 即時監控 cron 日誌
sudo journalctl -u cron -f
# 傳統的 syslog 方式(如果有啟用)
grep CRON /var/log/syslog
|
輸出重導向
將 cron 任務的輸出重導向到日誌檔案是最佳實踐:
1
2
3
4
5
6
7
8
| # 將標準輸出和錯誤都導向到日誌檔案
0 * * * * /path/to/script.sh >> /var/log/myjob.log 2>&1
# 分別記錄標準輸出和錯誤
0 * * * * /path/to/script.sh >> /var/log/myjob.log 2>> /var/log/myjob.error.log
# 帶時間戳記的日誌
0 * * * * /path/to/script.sh 2>&1 | while read line; do echo "$(date '+\%Y-\%m-\%d \%H:\%M:\%S') $line"; done >> /var/log/myjob.log
|
常見問題與解決方案
1. 環境變數問題
Cron 執行時的環境變數與互動式 shell 不同,可能導致腳本執行失敗:
1
2
3
4
5
6
7
8
| # 在 crontab 開頭設定環境變數
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
SHELL=/bin/bash
# 或在腳本中明確設定
#!/bin/bash
source /home/user/.bashrc
# 腳本內容...
|
2. 權限問題
確保腳本有正確的執行權限:
1
| chmod +x /path/to/script.sh
|
3. 路徑問題
在 cron 中使用絕對路徑:
1
2
3
4
5
| # 錯誤寫法
0 * * * * cd mydir && ./script.sh
# 正確寫法
0 * * * * cd /home/user/mydir && /home/user/mydir/script.sh
|
4. 測試 Cron 任務
手動測試腳本是否能在 cron 環境中正常執行:
1
2
| # 模擬 cron 環境執行腳本
env -i /bin/bash -c '/path/to/script.sh'
|
郵件通知
Cron 預設會將任務輸出透過郵件發送給使用者。可以在 crontab 中設定 MAILTO 變數:
1
2
3
4
5
6
7
8
| # 設定接收郵件的地址
MAILTO="admin@example.com"
# 停用郵件通知
MAILTO=""
# cron 任務
0 * * * * /path/to/script.sh
|
結語
Cron 是 Linux 系統中不可或缺的自動化工具。透過本文的介紹,您應該已經掌握了在 Ubuntu 22.04 中使用 cron 進行任務排程的基本技能。無論是簡單的定時備份還是複雜的系統維護任務,cron 都能幫助您實現自動化,提升工作效率。
建議在實際應用中:
- 總是將任務輸出重導向到日誌檔案
- 使用絕對路徑避免路徑問題
- 定期檢查日誌確保任務正常執行
- 先在測試環境驗證腳本再加入 cron
希望這篇文章對您有所幫助!