Dùng crontab để tự động chạy task trên Linux

Bạn có thể xử lý các công việc mệt mỏi, nhàm chán, khó khăn một cách tự động với crontab! Bây giờ chúng ta sẽ cùng tìm hiểu cron và crontab là gì.

Dùng crontab để tự động chạy task trên Linux
clock image
  • Mở đầu
  • Cron và crontab là gì?
  • Crontab format
  • Một số ví dụ

Mở đầu

  • Bạn nhận được yêu cầu backup database trên server vào lúc 1 giờ sáng hàng ngày.
  • Bạn phát hiện dung lượng ổ cứng trên server có dấu hiệu bất thường. Bạn muốn log dung lượng ổ cứng mỗi 10 phút.
  • Bạn muốn hiển thị một dòng nhắc nhở lúc 18:00 từ thứ Hai đến thứ Sáu:

Shut the f****** computer down and go home with your BEAR!

Bạn có thể xử lý các công việc mệt mỏi, nhàm chán, khó khăn trên một cách tự động với crontab!

Bây giờ chúng ta sẽ cùng tìm hiểu cron và crontab là gì.

Cron và crontab là gì?

Cron là gì?

Cron là một daemon thực thi các job (a.k.a task) đã được lên lịch trong các file crontab (cron table).

Cron tìm kiếm các file crontab của các user trong thư mục /var/spool/cron/crontabs vào load vào memory. Các file crontab được đặt tên giống với tên user. Chẳng hạn, user quangnv sẽ có 1 file tên là quangnv.

$ ls -l /var/spool/cron/crontabs
-rw------- 1 quangnv crontab 1133 Apr 12 08:59 quangnv

Chú ý là bạn chỉ cần biết sự tồn tại của thư mục này thôi, không nên trực tiếp thay đổi nó. Việc đó sẽ do crontab command thực hiện.

Ngoài các file crontab của user như trên, cron còn đọc các file crontab hệ thống /etc/crontab và các file trong thư mục /etc/cron.d.

Cron được kích hoạt mỗi phút, thực hiện các job đã load nếu nó được thiết lập để chạy ở thời điểm hiện tại.
Ngoài ra, cron cũng thực hiện kiểm tra các thư mục crontab mỗi phút một lần. Cron sẽ load các file crontab được thay đổi hoặc thêm mới. Do vậy, chúng ta không cần restart cron serivce khi thay đổi hoặc thêm mới các job.

Crontab command là gì?

Crontab command được sử dụng để quản lý các file crontab. Mỗi user có một file crontab trong /var/spool/cron/crontabs. Các job trong mỗi file crontab này sẽ được thực thi với quyền của user sở hữu nó.

Xem danh sách các job đã được thiết lập của user hiện tại:  

$ crontab -l

Xóa các job đã được lên lịch:  

$ crontab -r

Sửa file crontab (edit job list):  

$ crontab -e

Command này sẽ mở editor mặc định (vi, nano, ...) để bạn thêm/sửa/xóa danh sách cronjob. Tiếp theo, chúng ta sẽ tìm hiểu về crontab format.

Crontab format

Mỗi cronjob trong user crontab được viết với format sau:  

* * * * * /path/to/mycommand

5 dấu sao bên trên lần lượt thể hiện cho:

  • Phút (0~59)
  • Giờ (0~23)
  • Ngày trong tháng (1~31)
  • Tháng (1~12)
  • Ngày trong tuần (0~6, với 0 là Chủ nhật, hoặc sun, mon, tue, ...)

Như vậy, để thực hiện mycommand vào lúc 01:30 mỗi sáng Chủ nhật thì cronjob sẽ được viết như sau:  

30 1 * * 0 /path/to/mycommand

Mỗi cột thời gian còn chấp nhận các cách viết sau:

*
Đại diện cho tất cả các giá trị có thể.

-
Khoảng giá trị. Ví dụ: giá trị 6-9 ở cột giờ có nghĩa là thực hiện lúc 6h, 7h, 8h, 9h.

,
Liệt kê các giá trị. Ví dụ:
10,30,45 ở cột phút có nghĩa là thực hiện ở các phút 10, phút 30, phút 45. Kết hợp 8-10,13-15,18 ở cột giờ nghĩa là thực hiện lúc 8h, 9h, 10h, 13h, 14h, 15h, 18h.

/
Bước nhảy. Ví dụ:
*/15 8-12/2 * * *: thực hiện lúc 8:00, 8:15, 8:30, 8:45, 10:00, 10:15, 10:30, 10:45, 12:00, 12:15, 12:30, 12:45. Lưu ý là bước nhảy sẽ "reset" khi chuyển sang mốc thời gian tiếp theo. Ví dụ:
*/25 8,9 * * *: thực hiện lúc 8:00, 8:25, 8:50, 9:00, 9:25, 9:50 (9:15, 9:40)
0 0 */3 * *: thực hiện vào cả ngày 31/5 và 1/6

Chú ý: Nếu cả cột ngày trong thángngày trong tuần đều được gán giá trị khác *, thì job sẽ được thực hiện khi ngày hiện tại thỏa mãn ít nhất một trong 2 giá trị đó.
Ví dụ: với 0 5 1,15 * 1, job sẽ được thực hiện lúc 5:00 vào các ngày 1 và 15 hàng tháng thứ Hai hàng tuần.

Các chuỗi đặc biệt

Thay cho việc nhập giá trị vào 5 cột thời gian, chúng ta có thể dùng các chuỗi đặc biệt sau:

  • @reboot: thực hiện mỗi khi khởi động.
  • @yearly: thực hiện ngày 1/1 hàng năm, giống 0 0 1 1 *.
  • @annually: giống @yearly.
  • @monthly: thực hiện ngày 1 mỗi tháng, giống 0 0 1 * *.
  • @weekly: thực hiện vào ngày Chủ nhật hàng tuần, giống 0 0 * * 0.
  • @daily: thực hiện lúc nửa đêm mỗi ngày, giống 0 0 * * *.
  • @midnight: giống @daily.
  • @hourly: thực hiện mỗi giờ, giống 0 * * * *.

Một số ví dụ

Backup database vào lúc 1 giờ sáng hàng ngày  

0 1 * * * /usr/bin/backup_db.sh

Log dung lượng ổ cứng mỗi 10 phút  

*/10 * * * * /usr/bin/disk_usage_script.sh >> disk.log

Hiển thị một dòng nhắc nhở lúc 18:00 từ thứ Hai đến thứ Sáu:  

0 18 * * 1-5 echo 'Shutdown the computer and go home' > /dev/pts/0

Gửi email chúc mừng 20/10 tới các bạn nữ  

0 8 20 10 * /usr/bin/send_women_day_email.sh

Bonus:
http://crontab.guru/