Làm thế nào để thiết lập một công việc cron gốc đúng cách


36

Tôi đã cố gắng thiết lập một công việc cron gốc để chạy tập lệnh Bash với quyền root, để chạy vào phút 7,37, mỗi giờ, mỗi ngày trong tháng, mỗi tháng. Kịch bản này được đặt trong /usr/binvà được đặt tên tunlrupdate.sh. Nó cập nhật DNS của Tunlr.

$ ls -l /usr/bin/tunlrupdate.sh 
-rwxr-xr-x 1 root root 2133 Sep 24 15:42 /usr/bin/tunlrupdate.sh

Kịch bản Bash này có sẵn ở đây .

Khi được gọi, kịch bản ghi những gì xảy ra trong một bản ghi nằm ở /var/log/tunlr.log

Để thêm công việc cron gốc này, tôi đã sử dụng tiêu chuẩn cho crontab của root

sudo crontab -e

Và chèn 2 dòng này vào cuối. Tôi hy vọng cron chạy script như root.

# check for updated Tunlr DNS every 30 minutes at the hour + 7 mn and hour + 37 mn
07,37 * * * * root /usr/bin/tunlrupdate.sh

Một lệnh sau đó sudo crontab -lxác nhận rằng công việc cron đã được chèn.

Tôi đã khởi động lại Ubuntu và đang kiểm tra tệp nhật ký nếu công việc định kỳ được khởi chạy đúng cách. Tuy nhiên không có gì trong logfile /var/log/tunlr.logcó nghĩa là công việc chưa bao giờ được khởi chạy thành công.

Tôi đã kiểm tra xem nếu tôi chạy tập lệnh từ dòng lệnh

sudo /usr/bin/tunlrupdate.sh

sau đó logfile được cập nhật tương ứng.

Tại sao công việc định kỳ này không chạy theo kế hoạch trong hệ thống của tôi?

CẬP NHẬT 1: Tất cả các giải pháp đề xuất cho đến nay không hoạt động. Tôi cảm ơn Olli vì CLI để liệt kê nhật ký hệ thống sudo grep CRON /var/log/syslog. Tuy nhiên tôi đã nhận được một lỗi CRON

CRON[13092]: (root) CMD (  [ -x /usr/lib/php5/maxlifetime ] && [ -d /var/lib/php5 ]
&& find /var/lib/php5/ -depth -mindepth 1 -maxdepth 1 -type f -cmin +$(/usr/lib/php
/maxlifetime) ! -execdir fuser -s {} 2>/dev/null \; -delete)

với PATH được đề xuất = chèn và sử dụng đường dẫn tuyệt đối từ gốc cho các hàm trong tập lệnh hoặc không có giải pháp được đề xuất này ở đây. Tôi vẫn nhận được lỗi này.

Sau khi tìm kiếm, tôi xác định chính xác lỗi trong tệp /usr/lib/php5/maxlifetimenhư được giải thích ở đây :Change #!/bin/sh -e --> #!/bin/sh -x

Sau đó liệt kê nhật ký lỗi CRON trong hệ thống của tôi

sudo grep CRON /var/log/syslog
Feb 11 18:07:01 Marius-PC CRON[14067]: (root) CMD (root /usr/bin/tunlrupdate.sh)
Feb 11 18:07:01 Marius-PC CRON[14066]: (root) MAIL (mailed 1 byte of output; but got
status 0x00ff, #012)

Tôi vẫn không nhận được tập lệnh bash. Lần này không có lỗi được hiển thị trong nhật ký. Để đảm bảo đây không phải là nội dung của tập lệnh, tôi đã giảm tập lệnh thành 3 dòng sau:

#!/bin/bash
LOGFILE=/var/log/tunlr.log
echo $LOGFILE >> $LOGFILE

Tôi vẫn không nhận được công việc định kỳ thông qua. Không có gì được ghi trong tệp nhật ký. Vì vậy, thậm chí có thể là một tập lệnh trống sẽ không chạy trong cron? Tôi không hiểu Tôi biết việc thử một tập lệnh giảm xuống còn 2 dòng này:

#!/bin/bash
exit 0

Và vẫn là nhật ký lỗi tương tự. Kịch bản cron không đi qua ...


Nếu bạn muốn nó tạo ra một cronjob "root", bạn phải là root thì bạn gõ crontab -e. Ngoài ra, bạn chỉ cần đăng nhập bằng root (loại bàn điều khiển "su root") và sau đó crontab -e (sudo là không cần thiết trong trường hợp này).
Wolfgang

Tốt. Tôi không thấy câu trả lời của bạn? Nhập $ sudo crontab -e đã thực hiện công việc như được báo cáo bởi $ sudo crontab -l, tức là dòng mô tả công việc mới đã được thêm vào cron gốc. Vì mỗi công việc không có trong cron người dùng, ví dụ $ crontab -l không hiển thị bất kỳ công việc định kỳ nào đã được thêm vào đây.
Antonio

@WolfgangVogl anh ấy đã sử dụng "sudo" hoạt động như mong đợi.
Alexis Wilke

Câu trả lời:


68

Nếu bạn muốn chạy một tập lệnh như một người dùng bình thường :

crontab -e

Và thêm dòng:

07,37 * * * * /usr/bin/tunlrupdate.sh

Nếu bạn muốn chạy tập lệnh của mình dưới quyền root :

sudo crontab -e

Và thêm cùng một dòng:

07,37 * * * * /usr/bin/tunlrupdate.sh

@NineCattoRules Nếu bạn không giảm đầu ra, bạn thấy gì?
Fuchs

@AngeloFuchs bình luận cũ ... chắc chắn tôi đã thử lệnh đó với quyền root ( sudo crontab -ethay vì crontab -e). Hoặc một cái gì đó khác, dù sao nó cũng hoạt động
NineCattoRules

10

Vâng, cuối cùng các giải pháp làm việc. Trong syslog tôi thấy sự lặp đi lặp lại và hấp dẫn:

CRON[18770]: (root) CMD (root /usr/bin/tunlrupdate.sh)

Nghe có vẻ như root không được công nhận là cmd. Như tôi đã sử dụng cron của rễ bằng cách sử dụng $ sudo /usr/bin/tunlrupdate.sh. Sau đó, tôi đã thử với tập lệnh gốc (đã sửa lỗi trong ngày UNIX cmd:% m, tháng được sử dụng cho phút là% M) sau đây (loại bỏ gốc từ dòng cron):

$ sudo crontab -e
# check for updated Tunlr DNS every 30 minutes at the hour + 7 mn and hour + 37 mn
07,37 * * * * /usr/bin/tunlrupdate.sh

Điều này hóa ra là giải pháp cuối cùng. [Mặc dù tôi đã tìm thấy điểm số của văn học nêu rõ dòng sai lầm có gốc trong dòng cron. Đó là một sai lầm].


Điểm tốt của Olli. Tôi đồng ý với bạn về điều đó. Để tham khảo, người dùng crontab được lưu trữ trong / var / spool / cron / crontabs / tên người dùng hoặc cho root / var / spool / cron / crontabs / root. Xem trang này askubfox.com/questions/216692/where-is-the-user-crontab-stored Thư mục chứa đã có và cung cấp tên của người dùng.
Antonio

Chà, bạn không cần thông tin đó, vì bạn chỉ nên chỉnh sửa các tệp crontab bằng crontablệnh (ngoại trừ các tệp crontab bên dưới /etc).
Olli

1
@Antonio điểm số với trường tên người dùng chỉ được sử dụng trong /etc/crontab(crontab trên toàn hệ thống). Sử dụng sudo crontab -ebạn đang làm việc với crontab gốc thường có thể được tìm thấy trong/var/spool/cron/crontabs
Matijs

2

Một "vấn đề" với cron là thiếu các biến môi trường (vì lý do bảo mật rõ ràng ). Có lẽ bạn đang thiếu PATH và HOME. Bạn có thể xác định những người trong tập lệnh trực tiếp hoặc trong tập tin crontab.

# check for updated Tunlr DNS every 30 minutes at the hour + 7 mn and hour + 37 mn
PATH=/usr/bin
07,37 * * * * root /usr/bin/tunlrupdate.sh

Bạn sẽ phải kiểm tra cho đến khi tất cả các biến cần thiết được xác định theo yêu cầu của tập lệnh.


1
Đây là câu trả lời duy nhất ở đây thực sự làm việc cho tôi. Tôi đã sao chép các câu lệnh SHELL và PATH từ /etc/crontabtệp và dán chúng vào sudo crontab -evà lệnh chạy dưới quyền root mà không gặp vấn đề gì. Cảm ơn bạn!
Terrance

0

Thông báo lỗi cron thường - theo mặc định - được gửi qua email. Bạn có thể kiểm tra xem có email để root sudo mailhay không, hoặc chỉ kiểm tra nội dung của /var/mail/root, vd sudo less /var/mail/root.


Nếu email không giúp được, hãy kiểm tra /var/log/syslog:

sudo grep CRON /var/log/syslog

Như Alexis Wilke đã nói, cron có cơ chế khác nhau để thiết lập các biến môi trường.

Kịch bản của bạn cần

PATH=/sbin:/bin:/usr/bin

đến crontab. HOMEkhông cần thiết Bạn nên sử dụng các đường dẫn tuyệt đối trong tập lệnh của mình, ví dụ /bin/datethay vì date. Bạn có thể tìm thấy các đường dẫn thích hợp cho mỗi lệnh với which command_name, vd

$ which date
/bin/date

Chạy grep CRON được đề xuất của bạn trong / var / log / syslog Tôi đã bị lừa 11 tháng 2 14:37:01 Marius-PC CRON [7826]: (root) CMD (root /usr/bin/tunlrupdate.sh) 11 tháng 2 14: 37:01 Marius-PC CRON [7825]: (root) MAIL (được gửi 1 byte đầu ra; nhưng có trạng thái 0x00ff, # 012) 11 tháng 2 14:39:01 Marius-PC CRON [7849]: (root) CMD ( [-x / usr / lib / php5 / maxlifetime] && [-d / var / lib / php5] && find / var / lib / php5 / -depth -mindepth 1 -maxdepth 1 -type f -cmin + $ (/ usr / lib / php5 / maxlifetime)! -execdir fuser -s {} 2> / dev / null \; -delete) Nếu tôi thêm một số định nghĩa cho PATH trong cron thì những điều này sẽ không ảnh hưởng đến hệ thống của tôi $ PATH?
Antonio

Đầu ra đó cho biết họ đã cố gắng gửi email một cái gì đó nhưng không thành công. Điều đó có nghĩa là, bạn không nhận được thông báo lỗi đó /var/mail/root. Bạn có thể khắc phục điều đó hoặc thử vớiPATH=...
Olli

@Antonio, thay vào đó, sử dụng phiên bản vá lỗi
Olli

Cảm ơn. Tôi biết tôi đã không cấu hình e-mail hệ thống và nhận thức được rằng đã không đi qua. Tôi đã sửa đổi tập lệnh để sử dụng đường dẫn tuyệt đối cho bất kỳ chức năng nào được gọi. Điều cuối cùng là câu hỏi trước đây của tôi một định nghĩa PATH trong crontab sẽ không gây rối cho biến hệ thống $ PATH của tôi?
Antonio

1
Trong thời gian đó, tôi đang bận sửa một lỗi trong định dạng ngày từ tập lệnh gốc. Nó đã sử dụng% m (tính theo tháng KHÔNG phải phút) thay vì% M ...
Antonio

0

Bạn có thể thêm dòng này trong kịch bản của bạn. Vì vậy, sau khi bạn kiểm tra nhật ký cron và tính toán công việc của bạn đã được thực thi, bạn có thể nhận được cùng $ PATH của crontabs.

/bin/echo $PATH > /root/path.txt

Và có lẽ điều tốt nhất bạn có thể làm để chẩn đoán các vấn đề trong tập lệnh cron là lấy tất cả các biến môi trường của SO với lệnh env trong tập lệnh của bạn. Vì vậy, chỉ cần thêm dòng này vào kịch bản của bạn. Sau đó, bạn có thể phân tích đầu raallEvnVars.txt

/usr/bin/env > /root/allEvnVars.txt

Một mẹo khác là hướng đầu ra của tập lệnh đến một nơi nào đó. Thêm /root/log.log. Bằng cách này, tất cả đầu ra của tập lệnh sẽ được duy trì trong/root/log.log

07,37 * * * * root /usr/bin/tunlrupdate.sh  > /root/log.log

Ngoài ra, bạn có thể lên lịch cho tập lệnh chạy mỗi phút để tạo điều kiện cho các bài kiểm tra và kiểm tra.

*/1 * * * * root /usr/bin/tunlrupdate.sh  > /root/log.log
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.