Hướng dẫn crontab trên Ubuntu: Từ cơ bản đến nâng cao
Quản lý tác vụ tự động (scheduled tasks) là một kỹ năng rất quan trọng khi làm việc với Linux/Ubuntu. Công cụ quen thuộc nhất cho việc này là cron và file cấu hình của nó là crontab.
Bài viết này sẽ đi từ cơ bản đến nâng cao, kèm ví dụ cụ thể, để bạn có thể:
Đặt lịch chạy script / lệnh định kỳ
Ghi log, gửi email khi chạy cron
Dùng các biểu thức cron nâng cao
Tránh những lỗi “kinh điển” với crontab
1. Cron & crontab là gì?
cron: dịch vụ (daemon) chạy nền, chuyên thực thi các lệnh theo lịch.
crontab: file chứa danh sách các “job” mà cron sẽ chạy.
Có 2 kiểu crontab:
Crontab người dùng: cấu hình riêng cho từng user.
Crontab hệ thống: cấu hình chung, thường nằm ở
/etc/crontabhoặc trong các thư mục/etc/cron.*.
2. Các lệnh cơ bản với crontab
2.1. Mở và chỉnh sửa crontab
crontab -e
Lần đầu chạy, hệ thống có thể hỏi bạn chọn editor (nano, vim, …).
Lệnh này mở file crontab cá nhân của user hiện tại.
Nếu muốn chỉnh crontab cho user khác (cần quyền sudo):
sudo crontab -e -u username
2.2. Xem nội dung crontab
crontab -l
Xem crontab của user khác:
sudo crontab -l -u username
2.3. Xóa toàn bộ crontab
crontab -r
Xóa crontab của user khác:
sudo crontab -r -u username
Cẩn thận: -r sẽ xóa sạch tất cả job trong crontab. Có thể dùng -i để được hỏi lại:
crontab -ir
3. Cấu trúc dòng lệnh trong crontab
Mỗi dòng trong crontab (bỏ qua comment) có cấu trúc:
* * * * * command_to_run
│ │ │ │ │
│ │ │ │ └── Thứ trong tuần (0–7) (0 hoặc 7 = Chủ Nhật)
│ │ │ └──── Tháng (1–12)
│ │ └─────── Ngày trong tháng (1–31)
│ └────────── Giờ (0–23)
└───────────── Phút (0–59)
Ví dụ:
30 2 * * * /home/ubuntu/backup.sh
30: phút 302: 2 giờ sáng* *: mỗi ngày, mỗi tháng, mọi thứ trong tuần
Tức là: 2:30 sáng mỗi ngày.
4. Các ví dụ crontab cơ bản
4.1. Chạy lệnh mỗi phút
* * * * * /usr/bin/date >> /tmp/date.log 2>&1
Ghi thời gian hiện tại vào /tmp/date.log mỗi phút.
4.2. Chạy mỗi 5 phút
*/5 * * * * /path/to/script.sh
/5nghĩa là: mỗi 5 đơn vị (ở đây là phút).
4.3. Chạy hàng ngày vào giờ cố định
0h mỗi ngày:
0 0 * * * /path/to/daily_task.sh
23h30 mỗi ngày:
30 23 * * * /path/to/nightly_task.sh
4.4. Chạy hàng tuần
Mỗi Chủ Nhật lúc 1h sáng:
0 1 * * 0 /path/to/weekly_job.sh
(0 hoặc 7 đều có thể là Chủ Nhật, tùy hệ thống)
Mỗi Thứ Hai đến Thứ Sáu lúc 8h sáng:
0 8 * * 1-5 /path/to/workday_job.sh
4.5. Chạy hàng tháng
Ngày 1 mỗi tháng lúc 3h sáng:
0 3 1 * * /path/to/monthly_report.sh
5. Toán tử & ký hiệu thường dùng trong cron
Ngoài số và dấu *, cron hỗ trợ:
Dải (range):
1-5→ Từ 1 đến 5 (VD: thứ 2 đến thứ 6, hoặc ngày 1–5).
Danh sách (list):
1,3,5→ Giá trị 1, 3 và 5 (VD: chạy vào thứ 2, 4, 6).
Bước nhảy (step):
/10→ Mỗi 10 đơn vị.
5.1. Ví dụ kết hợp
Mỗi 10 phút, trong giờ hành chính (9h–17h):
*/10 9-17 * * * /path/to/office_task.sh
Chạy 3 lần mỗi ngày: 1h, 13h, 20h:
0 1,13,20 * * * /path/to/script.sh
6. Lệnh đặc biệt trong crontab (từ khóa “@”)
Nhiều hệ thống cron (Vixie cron / Debian cron) hỗ trợ các từ khóa dạng @something:
@reboot Chạy khi máy khởi động
@yearly Hoặc @annually – 1 lần/năm (tương đương 0 0 1 1 *)
@monthly 1 lần/tháng (0 0 1 * *)
@weekly 1 lần/tuần (0 0 * * 0)
@daily 1 lần/ngày (0 0 * * *)
@hourly 1 lần/giờ (0 * * * *)
6.1. Ví dụ
Chạy script mỗi khi máy reboot:
@reboot /path/to/init_script.sh
Gửi báo cáo mỗi ngày:
@daily /path/to/daily_report.sh
7. Quản lý đầu ra (output), log & email trong cron
Mặc định, output của cron có thể:
Gửi đến email của user (nếu hệ thống cấu hình MTA như
postfix,ssmtp, …).Bị bỏ qua (tùy cấu hình).
7.1. Ghi log vào file
Luôn luôn nên redirect output để debug dễ dàng:
0 2 * * * /path/to/backup.sh >> /var/log/backup.log 2>&1
>>: ghi nối vào cuối file.2>&1: gộp stderr (2) vào stdout (1).
7.2. Gửi email khi có output
Trên nhiều hệ thống, nếu có MAILTO trong crontab:
MAILTO="you@example.com"
0 2 * * * /path/to/backup.sh
Toàn bộ stdout/stderr sẽ được gửi tới email
you@example.com.
Nếu không muốn nhận mail:
0 2 * * * /path/to/backup.sh > /dev/null 2>&1
8. Các “pitfall” (lỗi hay gặp) với crontab
8.1. Biến môi trường khác với khi chạy tay
Cron chạy trong môi trường rất “sạch”, không giống khi bạn mở terminal. Vì thế:
PATHcó thể không chứa/usr/local/bin,~/bin, v.v.Các biến như
HOME,LANGcó thể khác.
Cách khắc phục:
Dùng đường dẫn tuyệt đối cho mọi thứ:
* * * * * /usr/bin/python3 /home/ubuntu/scripts/task.pyThiết lập PATH trong crontab:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 0 2 * * * /path/to/script.shNếu script cần nhiều biến môi trường, hãy set trong chính script.
8.2. Thư mục làm việc (working directory)
Cron không đảm bảo thư mục làm việc là thư mục chứa script.
Sai (hay gặp):
0 2 * * * ./run.sh
Đúng (đặt full path hoặc cd):
0 2 * * * cd /path/to/project && ./run.sh >> /var/log/project.log 2>&1
Hoặc sửa run.sh để tự cd vào đúng thư mục.
8.3. Quyền file & quyền user
crontab -e(không sudo) → crontab chạy với quyền của user hiện tại.sudo crontab -e→ crontab chạy với quyền root.
Lỗi thường thấy:
Dùng crontab user bình thường nhưng script cần quyền root (vd: ghi vào
/var/backups).File script không có quyền thực thi (
chmod +x).
Giải pháp:
Đảm bảo script executable:
chmod +x /path/to/script.shChọn user phù hợp (crontab cá nhân hoặc
root).
9. Crontab hệ thống & thư mục /etc/cron.*
Ngoài crontab cho từng user, Ubuntu còn dùng:
File
/etc/crontabThư mục:
/etc/cron.hourly//etc/cron.daily//etc/cron.weekly//etc/cron.monthly//etc/cron.d/
9.1. /etc/crontab
Mở bằng:
sudo nano /etc/crontab
Cấu trúc hơi khác: có thêm trường user:
# m h dom mon dow user command
17 * * * * root cd / && run-parts --report /etc/cron.hourly
Nghĩa là: chạy với quyền root.
9.2. /etc/cron.daily, cron.weekly, …
Các script trong các thư mục này được gọi tự động bởi cron hệ thống (thông qua /etc/crontab):
Đặt script vào
/etc/cron.daily/(nhớchmod +x) để nó chạy mỗi ngày.Tương tự với
cron.weekly,cron.monthly.
Ví dụ:
sudo cp /path/to/cleanup.sh /etc/cron.daily/cleanup
sudo chmod +x /etc/cron.daily/cleanup
10. Một số ví dụ nâng cao
10.1. Backup database MySQL mỗi đêm
0 2 * * * /usr/bin/mysqldump -u root -p'MATKHAU' mydb | gzip > /backup/mydb_$(date +\\\\%F).sql.gz 2>> /var/log/mysql_backup.log
Lưu ý:
Escape
%trong crontab:\\\\%(nếu không cron hiểu là ký tự đặc biệt).Mật khẩu để trong lệnh không an toàn, tốt hơn nên dùng file cấu hình
.my.cnf.
10.2. Xóa log cũ hơn 7 ngày mỗi đêm lúc 1h
0 1 * * * find /var/log/myapp/ -type f -mtime +7 -delete
10.3. Cron cho script Python (ảo môi trường)
*/15 * * * * cd /home/ubuntu/myproject && /home/ubuntu/myproject/venv/bin/python main.py >> /var/log/myproject.log 2>&1
cdvào projectDùng python trong virtualenv
Ghi log
11. Kiểm tra cron có chạy chưa & debug
11.1. Kiểm tra status cron
sudo systemctl status cron
Nếu chưa chạy:
sudo systemctl enable --now cron
11.2. Xem log cron
Tùy distro, log có thể ở:
/var/log/syslog/var/log/cron/var/log/messages
Trên Ubuntu thường:
grep CRON /var/log/syslog
Hoặc:
sudo journalctl -u cron
12. Checklist nhanh khi cron “không chạy”
Cron service có đang chạy? (
systemctl status cron)Đã dùng đường dẫn tuyệt đối cho:
Lệnh
Script
File log
Script có:
Quyền thực thi? (
chmod +x)Shebang đúng? (vd:
#!/bin/bash,#!/usr/bin/env python3)
Có
cdvào đúng thư mục nếu cần?Có ký tự
%chưa escape?Kiểm tra log cron (
grep CRON /var/log/syslog) và log riêng của script.
Kết luận
crontab là một công cụ cực kỳ mạnh nhưng cũng khá “khó chịu” nếu bạn không quen với:
Cú pháp thời gian (5 trường)
Môi trường chạy khác terminal bình thường
Vấn đề đường dẫn, quyền, log
Sau khi nắm vững:
Lệnh cơ bản (
crontab -e,l,r)Cú pháp lập lịch (dải, danh sách, bước nhảy, @daily, @reboot, …)
Kỹ thuật log & debug
bạn có thể tự động hóa hầu hết mọi công việc lặp lại trên server Ubuntu.