Crontab trong Linux: cú pháp và cách đặt lịch
Hướng dẫn Linux Server · cập nhật 21/08/2026
Crontab là bảng lịch của dịch vụ cron trên Linux, nơi bạn khai báo lệnh nào chạy vào lúc nào theo cú pháp năm trường thời gian. Mở bảng bằng crontab -e, thêm một dòng, lưu lại là xong, mất chưa tới 2 phút cho lịch đầu tiên.
Bạn cần tới crontab khi quản trị VPS hoặc máy chủ riêng: chạy script sao lưu mỗi đêm, xoá file tạm hàng tuần, gia hạn chứng chỉ SSL định kỳ, hoặc gọi một API theo chu kỳ. Dấu hiệu nhận ra là bạn có quyền SSH và cần một việc lặp lại mà không muốn ngồi canh.
- Mở bảng lịch của người dùng hiện tại bằng
crontab -e. - Viết một dòng gồm năm trường thời gian rồi tới lệnh cần chạy.
- Lưu và thoát, cron nạp lại bảng ngay không cần khởi động lại dịch vụ.
- Xem log để xác nhận lệnh đã được gọi đúng giờ.
Các lệnh trong bài chạy trên mọi bản Linux phổ biến gồm CentOS, Ubuntu và Debian. Tên gói dịch vụ khác nhau giữa các dòng: họ Red Hat gọi làcrond, họ Debian gọi làcron. Đường dẫn file log cũng khác, phần cuối bài nói rõ.
Cron chạy như thế nào và crontab nằm ở đâu
Cron là một tiến trình nền khởi động cùng hệ điều hành. Mỗi phút nó thức dậy một lần, đọc các bảng lịch, so thời điểm hiện tại với từng dòng, dòng nào khớp thì chạy lệnh của dòng đó. Vì chu kỳ quét là một phút nên đơn vị nhỏ nhất cron đặt được cũng là một phút.
Có nhiều bảng lịch cùng tồn tại trên một máy chủ, phục vụ mục đích khác nhau. Nhầm chỗ đặt là nguyên nhân khiến lịch chạy sai quyền hoặc không chạy.
| Nơi đặt lịch | Mở bằng cách nào | Chạy dưới quyền ai | Dùng khi nào |
|---|---|---|---|
| Crontab của người dùng | crontab -e | Chính người dùng đang mở | Việc riêng của một tài khoản, ví dụ script trong thư mục website |
/etc/crontab | Sửa file bằng trình soạn thảo | Người dùng ghi ở trường thứ sáu | Việc cấp hệ thống cần chỉ định người chạy |
/etc/cron.d/ | Tạo file mới trong thư mục | Người dùng ghi ở trường thứ sáu | Lịch đi kèm một phần mềm, dễ gỡ cùng phần mềm |
/etc/cron.daily/ và các thư mục cùng họ | Đặt script thực thi vào thư mục | Người dùng root | Việc chạy hàng ngày, hàng tuần, hàng tháng mà không cần giờ chính xác |
Khác biệt lớn nhất giữa crontab người dùng và /etc/crontab là số trường trên mỗi dòng. Crontab người dùng có năm trường thời gian rồi tới lệnh. File hệ thống có thêm một trường thứ sáu ghi tên người dùng, đặt giữa trường thời gian cuối và lệnh. Chép nhầm dòng từ chỗ này sang chỗ kia là cron hiểu tên người dùng thành một phần của lệnh.
Cú pháp năm trường thời gian của crontab
Mỗi dòng crontab bắt đầu bằng năm trường thời gian cách nhau bằng dấu cách hoặc tab, rồi tới lệnh. Cả năm trường phải cùng khớp thời điểm hiện tại thì lệnh mới chạy, trừ một ngoại lệ ở hai trường ngày sẽ nói ngay dưới.
* * * * * <lenh-can-chay>
- - - - -
| | | | +--- Ngày trong tuần (0-7, 0 và 7 là Chủ nhật)
| | | +----- Tháng (1-12)
| | +------- Ngày trong tháng (1-31)
| +--------- Giờ (0-23)
+----------- Phút (0-59)

| Trường | Khoảng giá trị | Ghi chú |
|---|---|---|
| Phút | 0–59 | Trường duy nhất quyết định cron chạy mấy lần trong một giờ |
| Giờ | 0–23 | Theo đồng hồ 24 giờ, nửa đêm là 0 |
| Ngày trong tháng | 1–31 | Đặt 31 thì tháng thiếu ngày sẽ bỏ qua |
| Tháng | 1–12 | Viết được cả tên viết tắt tiếng Anh như jan, feb |
| Ngày trong tuần | 0–7 | Số 0 và 7 đều là Chủ nhật, viết được sun, mon |
Ngoại lệ quan trọng: khi cả trường ngày trong tháng lẫn trường ngày trong tuần đều khác dấu sao, cron chạy lệnh nếu một trong hai khớp, chứ không phải cả hai. Dòng 0 0 1 * 1 chạy vào ngày 1 mỗi tháng và chạy cả mọi thứ Hai, chứ không phải chỉ ngày 1 rơi vào thứ Hai.
Bốn ký hiệu dùng trong mọi trường
| Ký hiệu | Nghĩa | Ví dụ | Kết quả |
|---|---|---|---|
* | Mọi giá trị của trường đó | * * * * * | Chạy mỗi phút |
, | Liệt kê nhiều mốc rời rạc | 0 9,18 * * * | Chạy lúc 9 giờ và 18 giờ hàng ngày |
- | Một khoảng liên tục | 0 12 * * 1-5 | Chạy 12 giờ trưa từ thứ Hai tới thứ Sáu |
/ | Bước nhảy trong khoảng | */10 * * * * | Chạy mỗi 10 phút |
Kết hợp được các ký hiệu trong cùng một trường. Dòng 0 8-18/2 * * 1-5 chạy mỗi 2 giờ trong khoảng từ 8 giờ tới 18 giờ, chỉ vào các ngày làm việc.
Các chuỗi viết tắt thay cho năm trường
Cron nhận một số chuỗi rút gọn bắt đầu bằng dấu a còng, viết thay cho cả năm trường. Chúng dễ đọc hơn nhưng không cho bạn chọn giờ chạy cụ thể.
| Chuỗi | Tương đương | Nghĩa |
|---|---|---|
@hourly | 0 * * * * | Đầu mỗi giờ |
@daily | 0 0 * * * | Nửa đêm hàng ngày |
@weekly | 0 0 * * 0 | Nửa đêm Chủ nhật |
@monthly | 0 0 1 * * | Nửa đêm ngày 1 mỗi tháng |
@reboot | không có | Chạy một lần mỗi khi máy chủ khởi động |
Thêm, xem và xoá lịch bằng lệnh crontab
Lệnh crontab quản lý bảng lịch của người dùng hiện tại. Ba tuỳ chọn dưới đây phủ gần hết việc thường ngày. Đừng sửa trực tiếp file trong /var/spool/cron, vì làm vậy bỏ qua bước kiểm cú pháp và cron có thể không nạp lại.
1. Mở bảng lịch để sửa
crontab -e
Lệnh mở bảng lịch trong trình soạn thảo mặc định, thường là vi hoặc nano. Lần đầu chạy trên tài khoản mới, hệ thống có thể hỏi bạn chọn trình soạn thảo. Thêm một dòng vào cuối file, lưu rồi thoát. Cron kiểm cú pháp lúc lưu, sai định dạng thì báo lỗi và giữ lại bản cũ.
Đặt trình soạn thảo quen tay bằng cách gán biến môi trường trước khi gọi lệnh:
EDITOR=nano crontab -e
2. Xem lịch đang có
crontab -l
In toàn bộ bảng lịch ra màn hình mà không mở trình soạn thảo. Chạy lệnh này trước mỗi lần sửa và lưu kết quả ra file để có bản dự phòng:
crontab -l > /root/crontab-backup-$(date +%F).txt
3. Xoá toàn bộ bảng lịch
crontab -r
Lệnh này xoá sạch bảng lịch của người dùng, không hỏi lại và không hoàn tác được. Nó nằm sát phím -e trên bàn phím nên gõ nhầm rất dễ. Dùng crontab -i -r để bắt hệ thống hỏi xác nhận trước khi xoá. Muốn bỏ một dòng thôi thì mở bằng crontab -e rồi xoá dòng đó, đừng dùng lệnh này.
Quản trị viên xem hoặc sửa bảng lịch của người dùng khác bằng tuỳ chọn -u:
crontab -u tendangnhap -l
Vì sao lệnh chạy tay được mà cron gọi thì im lặng
Đây là ca gây mất thời gian nhất với crontab, và nguyên nhân gần như luôn là môi trường chạy. Phiên đăng nhập SSH của bạn nạp đủ biến môi trường từ file cấu hình shell, còn cron chạy với một môi trường tối giản: biến PATH ngắn, không có biến riêng của bạn, thư mục làm việc là thư mục nhà.
Ba cách sửa, dùng kết hợp cả ba là chắc nhất:
- Gọi lệnh bằng đường dẫn tuyệt đối. Viết
/usr/bin/phpthay vìphp. Tìm đường dẫn thật bằngwhich phptrong phiên SSH rồi chép nguyên vào crontab. - Khai PATH ở đầu bảng lịch. Thêm một dòng gán biến trước các dòng lịch, cron nhận cú pháp này.
- Chuyển thư mục trước khi chạy. Script cần chạy trong thư mục cụ thể thì gộp hai lệnh bằng dấu chấm phẩy.
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
0 2 * * * cd /var/www/html; /usr/bin/php backup.php
Một bẫy cú pháp riêng của crontab: dấu phần trăm trong lệnh bị hiểu là ký tự xuống dòng. Lệnh có date +%F phải thoát thành date +\%F, không thì cron cắt lệnh ngay tại đó.
Đọc log để biết cron đã chạy hay chưa
Cron ghi lại mỗi lần gọi lệnh vào log hệ thống, kể cả khi bản thân lệnh im lặng. Log này cho bạn biết cron có gọi đúng giờ không, tách bạch với câu hỏi lệnh chạy có thành công không. Đường dẫn khác nhau giữa các dòng Linux.
| Dòng Linux | File log | Lệnh xem |
|---|---|---|
| CentOS, Rocky, AlmaLinux | /var/log/cron | tail -f /var/log/cron |
| Ubuntu, Debian | /var/log/syslog | grep CRON /var/log/syslog |
| Máy dùng systemd | nhật ký journal | journalctl -u crond -n 50 |
Dòng log chỉ nói cron đã gọi lệnh, không nói lệnh chạy đúng hay sai. Muốn giữ cả kết quả và thông báo lỗi của chính lệnh, chuyển hướng cả hai luồng ra một file riêng:
0 2 * * * /usr/bin/php /var/www/html/backup.php >> /var/log/backup.log 2>&1
Ký hiệu 2>&1 gộp luồng lỗi vào cùng file với luồng ra. Không có nó thì thông báo lỗi bị cron gửi qua email nội bộ và bạn thường không đọc tới. Muốn bỏ hẳn mọi kết quả cho một lịch chạy dày, đổi đích thành /dev/null.
Kiểm dịch vụ cron còn sống không, vì lịch đúng mà dịch vụ tắt thì không có gì chạy:
systemctl status crond
Các lỗi hay gặp khi viết dòng crontab
Sáu lỗi dưới đây chiếm phần lớn các ca crontab không như ý. Trừ lỗi đầu tiên, cả năm lỗi còn lại đều không sinh thông báo nào, cron im lặng làm sai ý bạn.
Lưu file báo lỗi cú pháp. Thiếu trường hoặc thừa trường. Đếm lại phải đúng năm trường thời gian trước lệnh, hoặc sáu trường nếu bạn đang sửa /etc/crontab.
Lệnh chạy 60 lần thay vì một lần. Trường phút còn để dấu sao trong khi trường giờ đã đặt số. Đặt phút thành một số cụ thể, thường là 0.
Lịch chạy nhiều hơn dự tính vào ngày lạ. Đặt cả trường ngày trong tháng lẫn ngày trong tuần. Chỉ đặt một trong hai, trường còn lại để dấu sao.
Lệnh bị cắt ngang giữa chừng. Trong lệnh có dấu phần trăm chưa thoát. Thêm dấu gạch chéo ngược trước mỗi dấu phần trăm.
Dòng cuối file bị bỏ qua. Crontab yêu cầu ký tự xuống dòng ở cuối file. Nhấn Enter sau dòng lịch cuối cùng trước khi lưu.
Chạy đúng lệnh nhưng sai múi giờ. Cron dùng múi giờ của hệ thống. Kiểm bằng timedatectl, máy chủ đặt theo giờ UTC thì lịch 2 giờ sáng của bạn thực ra chạy lúc 9 giờ sáng giờ Việt Nam.
Khi nào nên dùng cron và khi nào nên dùng cách khác
Cron hợp với việc lặp lại theo lịch cố định và chạy trong thời gian ngắn. Nó không theo dõi kết quả, không thử lại khi thất bại, và không ngăn hai lần chạy chồng lên nhau. Việc chạy 10 phút mà đặt lịch 5 phút một lần thì sau một giờ bạn có nhiều tiến trình cùng chạy song song.
Chặn chồng lấn bằng cách bọc lệnh trong flock, lần chạy sau bị bỏ qua nếu lần trước chưa xong:
*/5 * * * * /usr/bin/flock -n /tmp/backup.lock /usr/bin/php /var/www/html/backup.php
Nếu bạn dùng hosting dùng chung chứ không phải VPS, bạn không có quyền SSH để chạy các lệnh trên. Thao tác tương đương làm qua giao diện bảng điều khiển, xem cách tạo cron job trên DirectAdmin. Cú pháp năm trường trong bài này áp dụng nguyên vẹn cho các ô thời gian ở đó.