Lập Lịch Tasks Trên Linux Sử Dụng Crontab

Mở Đầu

Nếu bạn đang có một website mà nó "nặng nề" trên webserver, bạn có lẽ muốn chạy một vài tiến trình ví dụ như tạo ra những hình nhỏ hoặc thu thập dữ liệu ngầm. Theo cách này, nó không thể hiển thị với một giao diện người dùng. Linux có một chương trình tuyệt vời dành cho việc này. Nó cho phép các tác vụ chạy một cách ngầm tự động bên dưới đều đặn trong một khoảng thời gian. Bạn cũng có thể sử dụng nó để tự động sao lưu, đồng bộ files, lập lịch cập nhật và nhiều hơn thế nữa. Chào mừng đến với thế giới của crontab.

Giới Thiệu

Crontab (cron xuất phát từ "chronos", theo tiếng Hy Lạp có nghĩ là thời gian, tab là viết tắt của table), được tạo ra trên Unix và hoặc những hệ điều hành nhân Unix, thường dùng để lập lịch cho các câu lệnh để thực thi định kỳ. Để xem được những crontab nào đang chạy trên hệ thống của bạn, bạn có thể mở terminal và chạy:

sudo crontab -l

Để chỉnh sửa danh sách các crontab này, bạn có thể chạy:

sudo crontab -e

Nó sẽ mở trình soạn thảo mặc định (có thể là vi hoặc pico, có thể thay đổi trình soạn thảo mặc định nếu bạn muốn) để chúng ta thao tác với crontab. Nếu bạn lưu lại và thoát trình soạn thảo, tất cả cronjobs được lưu lại trong crontab. Cronjobs được viết theo định dạng sau:

* * * * * /bin/execute/this/script.sh

Như bạn đã nhìn thấy, có 5 dấu sao. Những dấu sao này thể hiện những thành phần khác nhau của ngày theo thứ tự sau:

  • minute - phút (0 - 59)
  • hour - giờ (0 - 23)
  • day or month - ngày trong tháng (0 - 31)
  • month - tháng (1 - 12)
  • day of week (0 - 6 ~ Sunday - Saturday)

Hướng Dẫn

Thực thi mỗi phút

Nếu bạn để toàn dấu sao, nó có nghĩa là "mỗi". Nó có lẽ hơi khó hiểu một chút. Hãy sử dụng ví dụ trước đó:

* * * * * /bin/execute/this/script.sh

Nó chứ toàn dấu sao nên nó sẽ thực thi

  • Mỗi phút
  • Trong mỗi giờ
  • Trong mỗi ngày
  • Trong mỗi tháng
  • Và mỗi ngày trong tuần

Nói ngắn gọn, kịch bản này được thực thi mỗi phút một lần, không có ngoại lệ.

Thực thi vào 1AM mỗi Thứ Sáu

Vậy nếu chúng muốn lập lịch cho kịch bản chạy vào 1 giờ sáng mỗi Thứ Sáu, chúng ta cần lệnh sau:

0 1 * * 5 /bin/execute/this/script.sh

Kịch bản này sẽ được thực thi khi giờ hệ thống:

  • minute - phút: 0
  • of hour - của giờ: 1
  • of day of month - Của ngày trong tháng: (every day of month)
  • of month - Của tháng: * (every month)
  • and weekdays - Và ngày trong tuần: 5 (=Friday)

Thực thi vào 1AM từ Thứ Hai đến Thứ Sáu

Nếu chúng ta muốn lập lịch chạy từ vào 1 giờ sáng từ Thứ Hai đến Thứ Sáu, chúng ta cần lệnh sau:

0 1 * * 1-5 /bin/execute/this/script.sh

Kịch bản này sẽ được thực thi khi giờ hệ thống:

  • minute - phút: 0
  • of hour - của giờ: 1
  • of day of month - Của ngày trong tháng: (every day of month)
  • of month - Của tháng: * (every month)
  • and weekdays - Và ngày trong tuần: 1-5 (=Monday-Friday)

Lập lịch một cách ngắn gọn

Điều gì xảy ra nếu bạn muốn chạy thứ gì đó cứ 10 phút một lần? Chúng ta có thể làm như sau:

0,10,20,30,40,50 * * * * /bin/execute/this/script.sh

Nhưng crontabs cho phép bạn thiết lập tốt hơn:

*/10 * * * * /bin/execute/this/script.sh

Nó làm điều tương tự như câu lệnh ở trên. Bạn có thể làm toán chứ? 😉

Từ khóa đặc biệt

Với dấu sao đầu tiên, bạn có thể sử dụng những từ khóa sau thay cho con số:

@reboot         Chạy một lần mỗi khi khởi động lại
@yearly          Chạy một lần mỗi năm    "0 0 1 1 *"
@annually     (Tương tự @yearly)
@monthly     Chạy  mỗi tháng một lần  "0 0 1 * *"
@weekly       Chạy mỗi tuần một lần  "0 0 * * 0"
@daily           Chạy một lần mỗi ngày    "0 0 * * *"
@midnight   (Tương tự @daily)
@hourly        Chạy một lần mỗi giờ    "0 * * * *"

Và bỏ trống những phần còn lại. Ví dụ:

@daily /bin/execute/this/script.sh

Lưu Crontab output

Mặc định, cron lưu output của kịch bản "/bin/execute/this/script.sh" trong hòm thư (mailbox) của người dùng. Nhưng tốt hơn là lưu output vào từng file log. Như ví dụ dưới đây:

*/10 * * * * /bin/execute/this/script.sh >> /var/log/script_output.log 2>&1

Linux có thể báo cáo nhiều cấp độ khác nhau. Có đầu ra chuẩn STDOUT và đầu ra lỗi STDERR. STDOUT đánh dấu là 1, STDERR đánh dấu là 2. Vậy, câu lệnh dưới đây báo cho Linux lưu STDERR trong STDOUT, tạo mội luồng dữ liệu cho thông báo và lỗi.

2>&1

Bây giờ, chúng ta có một output stream, chúng ta có thể lưu dữ liệu vào file. Ký hiệu ">" sẽ ghi đè file, trong khi ">>" sẽ thêm vào file. Trong trường hợp này, chúng ta muốn ghi thêm vào file

>> /var/log/script_output.log

Gửi crontab output qua email

Mặc định cron lưu output trong hòm thư của người dùng (trường hợp này là root) trong hệ thống cục bộ. Nhưng bạn cũng có thể cấu hình crontab để gửi toàn bộ output đến một địa chỉ thực sự bằng việc thiết lập một crontab bắt đầu bằng

MAILTO="[email protected]"

Nếu bạn muốn nhận chỉ crontab output trong mail, hãy chắc chắn gói này được cài đặt:

aptitude install mailx

và Đổi cronjob như sau:

*/10 * * * * /bin/execute/this/script.sh 2>&1 | mail -s "Cronjob ouput" [email protected]

Xóa crontab output

Nó thật dễ dàng:

*/10 * * * * /bin/execute/this/script.sh > /dev/null 2>&1

Chỉ dẫn mọi thứ đến "null device", giống như một hố đen. Trong những hệ điều hành nhân Unix, /dev/null là một file đặc biệt hủy bỏ tất cả dữ liệu viết lên nó.

Lưu ý

Rất nhiều kịch bản được thử trên môi trường BASH với biến môi trường PATH đã được thiết lập. Với cách này, nó cho phép kịch bản của bạn chạy trên shell. Nhưng nếu chạy cron nơi mà biến PATH khác đi, kịch bản sẽ không thể tìm thấy file thực thi và không chạy được. Việc thiết lập biến PATH không phải một phần trong crontab, nó là trách nhiệm của người thực thi, vì vậy sẽ hữu ích hơn nếu đặt một biến PATH ở đầu file (ngay phía sau MAILTO)

Kết Luận

Trước đây, mỗi khi tôi cần làm một công việc gì trên VPS (chủ yếu là sao lưu dữ liệu), tôi đều phải kết nối đến nó và thao tác một cách thủ công. Nhưng từ lúc biết được crontab, công việc đã dễ dàng di rất nhiều. Tôi đã thiết lập sao lưu tự động hằng ngày và không bao giờ còn lo về vấn đề này nữa. Đây chỉ là một ví dụ điển thình trong những việc mà tôi đã làm với crontab, thật là tuyệt vời đúng không nào? Tôi mong các bạn cũng sẽ tận dụng được crontab để giảm bớt được những thao tác thủ công mà ta phải làm đi làm lại hằng ngày, hàng giờ khi làm việc với Unix/Linux.

Chúc các bạn học tập và làm việc vui vẻ!

Tham Khảo

Schedule Tasks on Linux Using Crontab Crontab Setting Example