Khắc phục lỗi Cron-job không chạy

CRONJOB KHÔNG CHẠY

Khi sử dụng cronjob, ta thường gặp phải tình trạng cronjob đã setup đúng nhưng không chạy, một trong những nguyên nhân thường gặp là sự khác biệt giữa biến môi trường $PATH khi login vào terminal và khi chạy cronjob.
Mặc định, khi chạy cronjob, biến môi trường $PATH của tất cả user khi thực thi cron sẽ được set về
/usr/bin:/bin
Trong khi đó, nếu login terminal thì biến môi trường $PATH lại đa dạng hơn rất nhiều:
[root@blog.vietnix.vn ~]# echo $PATH /usr/local/openresty/bin:/usr/local/openresty/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

Do đó, rất nhiều trường hợp lệnh chạy ở terminal bình thường nhưng khi set cronjob thì không chạy được. Nguyên nhân là lệnh không nằm ở đường dẫn “/usr/bin” hoặc “/bin”. Vì là biến môi trường, điều này ảnh đến cả những lệnh được sử dụng trong script bash shell.

Ví dụ 1:
  • Login SSH bằng user root và chạy lệnh:
# Lấy PID của process httpd
[root@blog.vietnix.vn ~]# pidof httpd 
30772 30111 30110 30109 30108 30107 17540 5842 1165
  • Ở terminal, lệnh này hoạt động bình thường, ta setup 1 cronjob cho user root cho lệnh trên chạy định kỳ 
* * * * * pidof httpd >> /tmp/test.txt
  • Theo dõi file /tmp/test.txt, ta sẽ thấy kết quả không được update, kiểm tra /var/log/cron cho thấy cron đã được chạy:
/var/log/cron cho thấy cron đã được chạy
[root@blog.vietnix.vn ~]# cat /tmp/test.txt 
[root@blog.vietnix.vn ~]# tail /var/log/cron
May  6 12:03:01 blog CROND[30404]: (root) CMD (pidof httpd >> /tmp/test.txt)
May  6 12:04:01 blog CROND[30494]: (root) CMD (pidof httpd >> /tmp/test.txt)
May  6 12:05:01 blog CROND[30568]: (root) CMD (pidof httpd >> /tmp/test.txt)
May  6 12:06:01 blog CROND[30648]: (root) CMD (pidof httpd >> /tmp/test.txt)
May  6 12:07:01 blog CROND[30719]: (root) CMD (pidof httpd >> /tmp/test.txt)
May  6 12:08:01 blog CROND[30801]: (root) CMD (pidof httpd >> /tmp/test.txt)
May  6 12:09:01 blog CROND[30895]: (root) CMD (pidof httpd >> /tmp/test.txt)
May  6 12:10:01 blog CROND[30977]: (root) CMD (pidof httpd >> /tmp/test.txt)
May  6 12:10:46 blog crontab[31031]: (root) LIST (root)
May  6 12:11:01 blog CROND[31049]: (root) CMD (pidof httpd >> /tmp/test.txt)

Câu hỏi: Vì sao bước này mình lại đi kiểm tra mail của user root để xác định nguyên nhân cron không chạy?

Ví dụ 2:
  • Tương tự ví dụ 1, lúc này mình sẽ đưa lệnh pidof vào file Bash Shell: tạo file “/root/test.sh” có nội dung như sau:
#!/bin/bash
echo "----------"
echo $PATH >> /tmp/test.txt
pidof httpd >> /tmp/test.txt
  • File có nhiệm vụ in ra biến môi trường khi chạy cronjob và kết quả của lệnh pidof httpd vào file /tmp/test.txt.
  • Setup cronjob sử dụng đường dẫn tuyệt đối đến file “/root/test.sh”: 
 * * * * * /root/test.sh

  • Kết quả

  • Rõ ràng, biến môi trường có ảnh hưởng đến các lệnh nằm trong script được gọi bởi cronjob

KHẮC PHỤC

Nguyên nhân chính của tình trạng trên là do sự khác nhau của biến $PATH khi chạy trực tiếp trên terminal và bến $PATH khi được thực thi bởi cronjob. Để khắc phục, ta có thể dùng một trong 2 cách sau:
  • Sử dụng đường dẫn tuyệt đối khi chạy cron để bỏ qua sự tham gia của biến $PATH khi xác định vị trí lệnh cần chạy.
  • Khai báo lại biến $PATH khi chạy cron của user như sau:
  
   [root@blog.vietnix.vn ~]# crontab -l
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/home/blog
* * * * * /root/test.sh
  

Lưu ý: sử dụng “crontab -e” và khai báo lại biến $PATH như trên theo nhu cầu. Khi search trên mạng, sẽ có nhiều bài hướng dẫn các bạn chỉnh sửa file /etc/crontab, tuy nhiên đó không phải là cách làm đúng. File /etc/crontab không phải là file cấu hình cho dịch vụ cron, đây là file system wide cronjob, việc chỉnh sửa biến $PATH trong file /etc/crontab sẽ không giải quyết được vấn đề.

Đọc thêm

8 nhận xét

Đăng nhận xét