1. Cron là gì?

Cron là một tiện ích cho phép thực hiện các tác vụ một cách tự động theo định kỳ, ở chế độ nền của hệ thống. Crontab (CRON TABle) là một file chứa đựng bảng biểu (schedule) của các entries được chạy.

Học VPS mới bổ sung công cụ tạo Crontab với giao diện trực quan, rất dễ sử dụng. Mời các bạn tham khảo.

2. Cron làm việc thế nào?

Một cron schedule đơn giản là một text file. Mỗi người dùng có một cron schedule riêng, file này thường nằm ở /var/spool/cron. Crontab files không cho phép bạn tạo hoặc chỉnh sửa trực tiếp với bất kỳ trình text editor nào, trừ phi bạn dùng lệnh crontab.

Một số lệnh thường dùng:

crontab -e: tạo hoặc chỉnh sửa file crontab 
crontab -l: hiển thị file crontab 
crontab -r: xóa file crontab

Hầu hết tất cả VPS đều được cài đặt sẵn crontab, tuy nhiên vẫn có trường hợp VPS không có. Nếu bạn sử dụng lệnh crontab -l mà thấy output trả lại -bash: crontab: command not found thì cần tự cài crontab thủ công.

Cài đặt crontab

Sử dụng lệnh:

yum install cronie

Start crontab và tự động chạy mỗi khi reboot:

service crond start
chkconfig crond on

3. Cấu trúc của crontab

Một crontab file có 5 trường xác định thời gian, cuối cùng là lệnh sẽ được chạy định kỳ, cấu trúc như sau:

*     *     *     *     *     command to be executed
-     -     -     -     -
|     |     |     |     |
|     |     |     |     +----- day of week (0 - 6) (Sunday=0)
|     |     |     +------- month (1 - 12)
|     |     +--------- day of month (1 - 31)
|     +----------- hour (0 - 23)
+------------- min (0 - 59)

Nếu một cột được gán ký tự *, nó có nghĩa là tác vụ sau đó sẽ được chạy ở mọi giá trị cho cột đó.

Ví dụ:

– Chạy script 30 phút 1 lần:

0,30 * * * * command

– Chạy script 15 phút 1 lần:

0,15,30,45 * * * * command

– Chạy script vào 3 giờ sáng mỗi ngày:

0 3 * * * command

4. Ví dụ cụ thể

Giả sử mình viết một đoạn script sao lưu toàn bộ thư mục /home/domain.com/public_html/ và chuyển file nén .zip vào thư mục /root/ như sau:

#!/bin/bash
zip -r /root/backup_domain.com_$(date +"%Y-%m-%d").zip /home/domain.com/public_html/ -q

Script này lưu lại ở đường dẫn /etc/backup.sh (gán quyền execute – chmod +x nếu là bash script).

Sau đó mình cho script này chạy định kỳ vào 15h thứ Hai và thứ Năm hàng tuần bằng cách tạo một file crontab như sau:

crontab -e

Nhấn o (chữ o) để thêm dòng mới với nội dung:

0 15 * * 1,4 sh /etc/backup.sh

Để lưu lại và thoát bạn nhấn ESC, rồi gõ vào :wq nhấn Enter.

Cuối cùng, nhớ khởi động lại cron daemon:

/etc/init.d/crond restart

Nếu muốn dùng Editor nano sửa cho dễ thì bạn dùng lệnh sau: EDITOR=nano crontab -e

Ví dụ khác

– Để crontab chạy mỗi phút một lần:

* * * * * sh /etc/backup.sh

– Để crontab chạy 24h một lần (vào nửa đêm):

0 0 * * * sh /etc/backup.sh

– Để crontab chạy file PHP 24h một lần:

0 0 * * * /usr/bin/php /var/www/html/reset.php

5. Disable email

Mặc định cron gửi email cho người thực thi cron job, nếu bạn muốn tắt chức năng gửi email này đi thì hãy thêm đoạn sau vào cuối dòng

>/dev/null 2>&1

Ví dụ:

0 15 * * 1,4 sh /etc/backup.sh >/dev/null 2>&1

6. Tạo log file

Để lưu log vào file:

30 18 * * * rm /home/someuser/tmp/* > /home/someuser/cronlogs/clean_tmp_dir.log

Comment của bạn

Lưu ý: tất cả comment đều được kiểm duyệt cẩn thận! Nếu có code bạn hãy up lên pastebin.com rồi để lại link trong comment.

143 Comments

  1. Quốc Anh 38 comment

    Chào ad! Cho mình hỏi mình có 2 lệnh trong file crontab (1 cái gia hạn Let’s Encrypt và 1 cái là back up VPS) thì 2 lệnh có phải phân cách bằng dấu gì không? Hay chỉ cần mỗi lệnh 1 dòng khác nhau là đc? Cám ơn ad đã cung cấp quá nhiều kiến thức bổ ích mình 😀

    1. Việt Phương Moderator

      Mỗi lệnh 1 dòng là ok nhé bạn. Lúc bạn edit thì enter là xuống dòng

  2. snortsnort 2 comment

    Em chạy script ngoài terminal bình thường, nhưng khi đưa script vào chạy trong crontab thì lại không thực thi được là tại sao ạ ? Cron e tạo là : * * * * * sh /var/log/snort/script_upload.sh >/dev/null 2>&1

    1. Luân Trần Admin

      Bạn thử lệnh này coi sao: * * * * * /var/log/snort/script_upload.sh >/dev/null 2>&1

  3. Nguyen Dinh Phu 8 comment

    Có cách nào tạo cron job từ file php mà ko cần phải remote vps để nhập lệnh ko Luân ơi!

    1. Việt Phương Moderator

      Bạn chạy thủ công /sbin/reboot ok thì add vào crontab dòng này 0 0 * * * /sbin/reboot
      Reboot VPS lúc 0h00

    1. Việt Phương Moderator

      Đúng rồi. Nhưng bạn chạy mỗi lệnh curl http://domain.com/cron.php trên terminal SSH trc xem có tác dụng không thì crontab tự động chạy lệnh ý mỗi phút

        1. Việt Phương Moderator

          Thường vấn đề nằm ở lệnh chứ không ở cron. Không nhầm thì bạn cần wget cái php cronjob ý chứ không phải curl
          Còn kiểm tra cron bạn xem service crond status và nội dung /var/log/cron sẽ thấy lệnh ý có được chạy mỗi phút không

          1. Nguyễn Quốc Thông 4 comment

            lệnh này * * * * * wget http://domain.com/botlike.php
            nó báo lỗi -bash: *: command not found
            Giúp với ạ

          2. Việt Phương Moderator

            Nó là trong crontab không phải lệnh ngoài. Khi đó * hiểu là thời gian, không phải lệnh thực thi. Lệnh thực thi tính từ wget
            Còn nếu chạy ở terminal mới là wget http://domain.com/botlike.php

          3. Việt Phương Moderator

            Như mình bảo đó. wget http://domain.com/botlike.php là chạy bên ngoài. Còn add vào crontab thì add * * * * * wget http://domain.com/botlike.php

    1. Việt Phương Moderator

      1. Lệnh đó bạn chạy ở terminal được bình thường?
      2. 0 0 8 * * * curl http://localhost/csm/index.php/cronjob bạn nhé. Xong bạn kiểm tra log ở /var/log/cron xem chạy không

      1. Nguyễn Danh Phương 4 comment

        Trong /var/log/ không thấy bác ạ. Lệnh nào để kiểm tra vậy bác?

        1. Quách Chí Cường 7 comment

          Bạn xài CentOS thì thường có log cron ở ‘/var/log/cron’.

          # tail -f /var/log/cron

          1. Bạn check xem service cron có chạy không ?
          # ps auxfw | grep -v “grep” | grep -i “cron”

          -> Nếu chưa start cron thì start lên.
          # service cron start

          2. Bạn check thử trường hợp, thời gian dịch vụ cron sử dụng có bị lệch time với thời gian hệ thống hay không ? Có thể tham khảo bài này : https://cuongquach.com/linux-fix-loi-cronjobs-chay-sai-gio-he-thong.html

          3. Nếu cron chưa được cài trên OS của bạn, thì kiểm tra cài lại như trong bài nhé.

          Thân.

  4. Hùng 12 comment

    mình đang dùng host cpanel và dùng cron job trên cpanel chạy các lệnh dưới đó. Mình muốn chuyển qua VPS nhưng không biết trên VPS chạy các lệnh như ở dưới như thế nào cho cái plugin nó làm việc

    Once Per Hour Cron URL: wget -O /dev/null http://www.vvvlives.com/wp-content/plugins/Machine/auto.php
    Once Per Day Cron URL: wget -O /dev/null http://www.vvvlives.com/wp-content/plugins/Machine/auto2.php
    Twice Per Hour Cron URL: wget -O /dev/null http://www.vvvlives.com/wp-content/plugins/Machine/auto3.php

      1. Việt Phương Moderator

        Hình nhưu bạn thiết lập sai về thời gian chạy của dòng lệnh. Thường lỗi do đã xuống dòng trong 1 dòng lệnh.
        Ví dụ 0 2 * * * wget –spider -O – http://abc.xyz/index.php/cronjob/post > /dev/null 2>&1 để chạy lệnh của bạn lúc 2h AM hàng ngày

  5. hoàng 1 comment

    xác nhận ghi lại người đăng nhập hệ thống tần xuất 1h/1 lần vào file log.txt thì phải làm sao ạ

  6. Vy 1 comment

    Chào anh Luân.
    Cho em hỏi làm thế nào để tự động backup website ở VPS Vultr về vps lưu trữ tại Ramnode với ạ?
    Anh có thể gợi ý các bước hay chương trình cần dùng, em có thể tự tìm hiểu kỹ hơn.

    1. Việt Phương Moderator

      Có thể hiểu là user root chưa có bất kỳ 1 lịch chạy nào trong crontab nên # crontab -l báo thế. Kiểm tra lại crontab file bạn tạo nhé

  7. Nguyen Quang Trinh 1 comment

    Anh Luân giúp em viết đoạn script tự động khởi động lại firefox với ạ.

  8. Nhân 1 comment

    Mọi người cho mình hỏi email admin set ở đâu thế.
    Còn crontab thì sao canh 2 ngày chạy được mọi người nhỉ, nếu tháng 31 ngày thì có vẻ ko ổn.
    Cảm ơn mọi người

  9. Thi Nguyen 1 comment

    Mình có sử dụng crontab , tuy nhiên tính năng này tự động lưu các file về thư muc root (/home) làm nhiều dữ liệu của mình bị chồng lên nhau. Có cách nào phân loại ra không vì mình chạy 2 đoạn crontab.

    Cảm ơn bạn đã hỗ trợ

  10. nanami 1 comment

    hi anh
    cho em hỏi tại sao em sửa nội dung file script. khi chạy trực tiếp script thì cho ra kêt quả đúng. Nhưng khi dùng crontab chạy script đấy thì lại ra kết quả khác ?

  11. Phước 1 comment

    Em cài hocvps trên vultr tạo cron xong e chạy “/etc/init.d/crond restart” nhưng nó báo lỗi “No such file or…” xử lý thế nào anh

  12. Chu Tiến Diện 1 comment

    [bug]: chào cả nhà:
    khi em chạy cronjob nó có báo lỗi như sau exec() has been disabled for security reasons
    và mã lệnh thực thi của em chưa có hiệu lực

    Mọi người có thể giúp em được ko ạ

    1. Luân Trần Admin

      Bạn mở file /etc/php.ini ra, tìm dòng disable_function rồi xóa exec đi, restart php-fpm là được.

    2. khai 2 comment

      Hi anh Luân em cài đặt giống thế.nhưng khi chạy crontab không thấy hiện tượng gì.
      a có skype support giúp e phát.em cảm ơn.

        1. khai 2 comment

          em cảm ơn anh.em tìm hiểu được rồi anh ạ.đó là file log của em được nghi ở thư mục khác

  13. Cao Tri 1 comment

    Luân cho mình hỏi:

    Mình tạo 1 script lưu trong /home/mycount/optimize_db.sh với nội dung
    #!/bin/bash
    mysqlcheck -c mydb -u xxx -pyyy

    Định kỳ vào x giờ 50 phút mình chạy cron với lệnh:
    50 3,4,5,6,15,10 * * * sh /home/mycount/optimize_db.sh

    1) Cho mình hỏi cron và nội dung trong script có đúng không?
    2) Làm sao để email kết quả cron này cho một email chỉ định ví dụ abc@abc.com hoặc lưu kết quả trả về vào file log do mình chỉ định? (Mình muốn biết cron này có chạy không và chạy có đúng không/)

    Cảm ơn rất nhiều.

  14. Hoàn Trần 2 comment

    Bác Luân em hỏi một chút, có cách nào để setup 1 cái crontab hoặc 1 cái binbash tự động chạy sau khi reboot lại vps không ạ? em đang muốn 1 vài giòng lệnh sẽ tự động chạy sau khi khởi động lại vps như kiểu lệnh chconfig cho ứng dụng ấy ạ

      1. Hoàn Trần 2 comment

        Anh Luân em hỏi thêm 1 chút ạ, em đang dùng dedi trên vultr và có 2 địa chỉ ip, nhưng sau mỗi lần reboot server thì con ip thứ 2 không tự động khởi chạy mà em phải tiến hành restart network lúc đó nó mới chạy được. Có cách nào để nó tự động khởi chạy khi mà mình restart server không anh nhỉ

  15. WinKK 2 comment

    Bác Luân có set cron cho user khác root chưa nhỉ
    mình đang add thử thêm user test và thử add cron với quyền test:
    /usr/bin/date >> /tmp/_debug_log/date.log
    không hiểu sao mà nó hem ghi dc log luôn, quay tay trực tiếp bằng cách bấm run trong webmin thì có ghi đc log
    ko biết có phải set thêm quyền gì cho nó không nhỉ?

    1. Luân Trần Admin

      Mình chưa thử bao giờ, nhưng nếu có vấn đề thì chỉ ở khoản phân quyền các thứ thôi. Bác trực tiếp login vào account test rồi chạy thử xem có được không chưa?

  16. Nam Thanh 36 comment

    Cho em hỏi, em dùng 1 plugin, nó yêu cầu set cron với command như sau (command này do plugin tự tạo và em start command test trên site thì chạy tốt): curl http://domain.com/?wp_automatic=autofeed

    “autofeed” là keyword cho cái Cron đó, mình có thể thay đổi nếu muốn.

    Vậy nên em set trong crontab như sau, muốn chạy 1 phút mỗi lần:
    1 * * * * curl http://domain.com/?wp_automatic=autofeed

    Tuy nhiên sau 1 phút thì ko thấy chạy cron theo như yêu cầu, em xem log cron bằng lệnh tail -f /var/log/cron thì thấy có vẻ như cron không chạy

    Thông tin thêm là em dùng vps vultr, config theo hocvps script, cài crontab theo như anh hướng dẫn đồng thời restart lại cron daemon

    1. Nam Thanh 36 comment

      Sau một hồi suy nghĩ em làm lại như vầy nhưng vẫn ko chạy đc ạ:
      1 * * * * /home/domain.com/public_html/wp-content/plugins/automatic/cron.php?wp_automatic=autofeed

      Vì plugin này có 1 file cron.php trong đó có function wp_automatic. Em truyền vào như vậy nhưng chưa thấy hiệu quả.

  17. NguyenTung 43 comment

    Cảm ơn bác, reboot em làm ok rồi ạ

    ————-

    Chào bác Luân,

    Các file sau:
    /var/log/secure
    /var/log/lfd.log
    /var/log/messages
    /var/log/maillog

    Em thấy ngày càng to ra
    Nếu em xoá đi thì có sao không vậy bác
    Mong bác hồi âm

    1. Luân Trần Admin

      Server của bạn có khả năng bị hack, sử dụng để spam mail rồi.
      Phải có vấn đề gì đó thì log file mới ngày càng nhiều, check lại cẩn thận nhé bạn.

  18. NguyenTung 43 comment

    HI ok,
    Em đã làm được rồi bác à, làm lần lượt hehe
    Bác cho em hỏi bổ sung dòng lệnh crontab:
    2h30 phút hàng ngày thì server restart ạ

    Cảm ơn bác

  19. NguyenTung 43 comment

    Cảm ơn bác đã hồi âm
    Ý em muốn hỏi là dòng lệnh trên có sai không ạ
    crontab -e 0 2 * * * /bin/bash rm -f /var/log/php-fpm/*.*
    Nếu sai thì sửa như thế nào
    Cái em cần là xoá file log sinh ra tại /var/log/php-fpm/ hàng ngày vào lúc 2h sáng giờ Hà Nội
    Mong bác giúp đỡ

  20. NguyenTung 43 comment

    Chào bác Luân
    Em cần xoáy file log sinh ra tại /var/log/php-fpm/ hàng ngày vào lúc 2h sáng giờ Hà Nội
    Em thực hiện lệnh như sau:
    crontab -e 0 2 * * * /bin/bash rm -f /var/log/php-fpm/*.*

    Nhưng mà khi thực hiện lệnh trên thì thấy báo lỗi:

    crontab: invalid option — ‘f’
    crontab: usage error: unrecognized option
    usage: crontab [-u user] file
    crontab [-u user] [ -e | -l | -r ]
    (default operation is replace, per 1003.2)
    -e (edit user’s crontab)
    -l (list user’s crontab)
    -r (delete user’s crontab)
    -i (prompt before deleting user’s crontab)
    -s (selinux context)
    You have mail in /var/spool/mail/root

    Nhờ bác chỉ giúp

    Cảm ơn bác nhiều nhé

    1. Luân Trần Admin

      Bạn dùng lệnh này để sửa cron với nano cho dễ: EDITOR=nano crontab -e
      Add lệnh muốn chạy vào rồi nhấn Ctrl+O lưu lại rồi Ctrl+X để thoát

  21. Truong Anh Khoa 2 comment

    Chào Luân ! . Minh chưa hiểu về cronjob lắm nên có thể cách diễn đạt ko tốt lắm -_-
    Mình có 1 cái file nằm trong project có cấu trúc như sau : project/apps/action.php, và web của mình là : comment.fptultimate.com
    mình dung hocvps và câu lệnh mình sử dụng để cấu hình 1 phút chạy 1 lần
    * * * * * wget -O /dev/null http://comment.fptultimate.com/apps/action.php
    Không biết thế nào mà nó ko thực thi mà cũng không thông báo lỗi hay gì hết.
    Mình đã test thử 1 file action khác thì nó thực hiện bình thường(2 file action có nội dung khác nhau- ở đây mình đã đổi tên để trung với câu lệnh của * * * * * wget -O /dev/null http://comment.fptultimate.com/apps/action.php ). Mong được giúp đở

  22. Quan Nguyen 1 comment

    Chào a, a có thể hướng dẫn e viết Crob Job để backup dữ liệu trên VPS của DigitalOcean được không a?

  23. DUC 3 comment

    Chào Luân

    Mình cần định kỳ xóa thư mục: ví dụ: home/domain.com/cache
    bây giờ mình phải làm sao ? mong được hướng dẫn ,

    cám ơn

    1. Luân Trần Admin

      Câu lệnh để xóa là rm -rf /home/domain.com/cache/*
      Bạn kết hợp thêm với crontab là được

  24. ABA 8 comment

    Bạn Luân cho mình hỏi về cronjob, mình làm các kiểu như lệnh dưới nhưng không hoạt động. Mình dùng VPSSIM để quản lý Cronjob. Vậy sai ở chỗ nào, bạn sửa giùm mình được không ?

    * * * * * /usr/bin/php /home/domain.net/public_html/cron.php?name=ABA&gl=delete
    * * * * * /usr/sbin/php-fpm /home/domain.net/public_html/cron.php?name=ABA&gl=delete
    * * * * * /usr/bin/wget /home/domain.net/public_html/cron.php?name=ABA&gl=delete
    * * * * * /usr/bin/wget -q /home/domain.net/public_html/cron.php?name=ABA&gl=delete
    * * * * * /usr/bin/wget -o /home/domain.net/public_html/cron.php?name=ABA&gl=delete
    * * * * * /usr/bin/wget -q http://domain.net/cron.php?name=ABA&gl=delete
    * * * * * /usr/bin/wget -o http://domain.net/cron.php?name=ABA&gl=delete
    * * * * * curl http://domain.net/cron.php?name=ABA&gl=delete
    * * * * * wget http://domain.net/cron.php?name=ABA&gl=delete

    1. Luân Trần Admin

      Bạn muốn chạy thế nào, hàng ngày, hàng giờ? Mình ko thấy cấu hình

  25. maitrinh 2 comment

    Cảm ơn bạn nhé.. Mình k biết nhiều về linux toàn lên mạng tìm kiếm câu lệnh nên k biết..

  26. maitrinh 2 comment

    Bạn ơi khi chạy crontab mình dùng wget nhưng khi chạy xong nó hay lưu file ra đĩa.. Bạn có thể chỉ cho mình làm sao để k cho nó lưu file sau khi chạy được không
    câu lệnh của mình có dạng * * * * * wget http://abc.xyz/auto.php > /dev/null 2>&1
    Cảm ơn bạn!

  27. loing 2 comment

    Đây là crontab của mình , cứ 2 phút cho chạy dòng lệnh sau: 2 * * * * /usr/sbin/php-fpm /home/domain.com/public_html/txt.php

    Trong file php mình đã thêm dòng #!/usr/local/bin/php -q
    Kiểm tra nó vẫn không hoạt động, Luân xem mình đang gặp lỗi gì vậy

    1. Luân Trần Admin

      Cái này do nội dung bạn thực hiện cái gì, mình chịu thua không support được nhé 😀

  28. loing 2 comment

    Mình dùng HocVps thì path php thế nào hả bạn VD: 0 * * * *pathPHP /home/domain/txt.php

  29. haxuan 13 comment

    Bạn hướng dẫn chỗ gõ crobtab -e xong rồi làm sao nữa. Ví dụ cụ thể luôn:
    cron job của mình là * * * * * /usr/bin/wget –spider \”http://www.domain.com/cron.php\” >/dev/null 2>&1
    giờ mình vướng chỗ gõ crobtab -e xong không biết insert cái command trên như thế nào ?

    1. Luân Trần Admin

      Chào bạn, mình giờ đã hiểu vấn đề của bạn rồi.
      Mặc định khi edit crontab sẽ sử dụng vim editor, hơi khó sử dụng với người mới bắt đầu. Mình đã update lại bài viêt, bạn xem thử xem đã thực hiện theo ok chưa nhé.

  30. haxuan 13 comment

    Có thể hướng dẫn mình cụ thể hơn được không ?
    1. crontab -e
    2. mình đánh dòng lệnh rồi mà không biết add vô thế nào ? enter không nhúc nhích gì