Làm cách nào để tạo crontab thông qua tập lệnh


153

Tôi cần thêm một công việc định kỳ thông qua một tập lệnh tôi chạy để thiết lập một máy chủ. Tôi hiện đang sử dụng Ubuntu. Tôi có thể sử dụng crontab -enhưng điều đó sẽ mở một trình soạn thảo để chỉnh sửa crontab hiện tại. Tôi muốn làm điều này theo chương trình.

nó có khả thi để làm vậy không?




Nếu bạn đang tìm cách sửa đổi hoặc xóa một mục crontab, hãy xem giải pháp của tôi dưới đây.
Brian Smith

Câu trả lời:


12

Các công việc định kỳ thường được lưu trữ trong tệp theo người dùng bên dưới /var/spool/cron

Điều đơn giản nhất để bạn làm có lẽ chỉ là tạo một tệp văn bản với công việc được cấu hình, sau đó sao chép nó vào thư mục bộ đệm cron và đảm bảo rằng nó có quyền phù hợp (600).


19
Sửa đổi các tệp trực tiếp trong / var / spool / cron được tán thành. Trên thực tế, nếu bạn xem các tệp ở đó, chúng thường sẽ chứa các cảnh báo như "KHÔNG CHỈNH SỬA NÀY" như dòng đầu tiên.
Jared

12
@Jared Trong khi tôi khá đồng ý với ý kiến ​​đó, nói rằng nó "được tán thành" không giúp được gì nhiều. Thay vì nói tập tin nào khác cần được chỉnh sửa, nếu có, hoặc giải thích các rủi ro của việc chỉnh sửa tập tin theo cách thủ công. Tôi dự định tạo một số công việc định kỳ thông qua dòng lệnh tự động và nếu chỉnh sửa tệp này là cả hai tùy chọn duy nhất và không có tác dụng phụ đáng kể, tôi không hiểu tại sao tôi không nên sử dụng nó.
Balmipour

47
Cuộn xuống cho câu trả lời thực sự.
John Red

1
Theo tôi, câu trả lời này là cách tốt hơn: stackoverflow.com/a/610860/2681752
galaux

2
Tôi đã thực hiện phương pháp này và hối tiếc. Trên RHEL, thư mục / var / spool / cron không thể thực thi được trên thế giới, vì vậy người dùng không thể duyệt qua thư mục và chỉnh sửa các tệp của họ theo cách thủ công. Nếu bạn thực hiện / var / spool / cron thế giới thực thi, sysadmin địa phương thân thiện của bạn sẽ nổi giận với bạn, cộng với thay đổi quyền có thể được ghi đè nếu gói cronie được cài đặt lại hoặc cập nhật.
functionvoid

384

Đây là một lớp lót không sử dụng / yêu cầu công việc mới phải ở trong một tệp:

(crontab -l 2>/dev/null; echo "*/5 * * * * /path/to/job -with args") | crontab -

Điều 2>/dev/nullquan trọng là bạn không nhận được no crontab for usernamethông báo mà một số * nixes tạo ra nếu hiện tại không có mục crontab.


14
Đây phải là câu trả lời được chấp nhận. Chỉ cần một cách bây giờ để kiểm tra xem lớp lót mà tôi dự định thêm đã có ở đó hay chưa ...
ChrisPrime

7
... oh chờ đã, đây là cách kiểm tra xem có thứ gì trong crontab của người dùng của tôi không trước khi tôi thêm nó vào tập lệnh: stackoverflow.com/a/14451184/3686125
ChrisPrime 14/12/14

1
nếu tập lệnh này được dự định là một lệnh được lặp lại và sửa đổi một tác vụ cron hiện có, thì có thể tốt hơn để thay thế dòng hiện có trong crontab. một số điểm đánh dấu có thể được sử dụng để kiểm soát các tác vụ cron khác nhau (control-Marker-1, control-Marker-2, v.v.): (crontab -l 2> / dev / null | grep -v control-Marker-1; echo '* / 5 * * * * / path / to / job -with args # control-Marker-1') | crontab -
đầu bếp

7
Tôi thấy rằng điều này đã loại bỏ các mục crontab hiện có và tôi cũng cần sử dụng một người dùng khác (root) vì vậy tôi đã sử dụng các mục sau để duy trì các mục hiện có: echo -e "$(sudo crontab -u root -l)\n* * * * * echo hello > /home/danny/temp.log 2>&1" | sudo crontab -u root -Hy vọng điều này sẽ giúp được ai đó
Danny

60

Đối với người dùng crontabs (bao gồm cả root), bạn có thể làm một cái gì đó như:

crontab -l -u user | cat - filename | crontab -u user -

trong đó tệp có tên "tên tệp" chứa các mục để chắp thêm. Bạn cũng có thể thực hiện thao tác văn bản bằng cách sử dụng sedhoặc một công cụ khác thay thế cat. Bạn nên sử dụng crontablệnh thay vì trực tiếp sửa đổi tập tin.

Một hoạt động tương tự sẽ là:

{ crontab -l -u user; echo 'crontab spec'; } | crontab -u user -

Nếu bạn đang sửa đổi hoặc tạo crontabs hệ thống, chúng có thể bị thao túng như các tệp văn bản thông thường. Chúng được lưu trữ trong /etc/cron.d, /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly, /etc/cron.monthlythư mục và các tập tin /etc/crontab/etc/anacrontab.


Có vẻ đầy hứa hẹn nhưng đang thử cách tiếp cận thứ hai (với echo), tôi đã nhận được "crontab: lỗi sử dụng: tên tệp phải được chỉ định để thay thế." Trang cron man hiển thị cú pháp như crontab [ -u user ] file, nghĩa là, với một tên tệp bắt buộc. Có một số mẹo để làm cho nó chấp nhận dữ liệu đường ống thay thế?
Mark Berry

1
@Mark BlackBerry: Xin lỗi về điều đó. Trong một đường ống, một dấu gạch nối phải được sử dụng để chỉ ra rằng đầu vào là từ stdin. Tôi sẽ sửa câu trả lời của tôi.
Tạm dừng cho đến khi có thông báo mới.

29

Trong Ubuntu và nhiều bản phân phối khác, bạn chỉ cần đặt một tệp vào /etc/cron.dthư mục chứa một dòng duy nhất có mục crontab hợp lệ . Không cần thêm một dòng vào một tập tin hiện có.

Nếu bạn chỉ cần một cái gì đó để chạy hàng ngày, chỉ cần đặt một tập tin vào /etc/cron.daily. Tương tự như vậy, bạn cũng có thể thả file vào /etc/cron.hourly, /etc/cron.monthly/etc/cron.weekly.


5
Nhưng bạn phải root để làm điều này.
Keith

17

Câu trả lời đơn giản hơn cho câu hỏi của bạn sẽ là:

echo "0 1 * * * /root/test.sh" | tee -a /var/spool/cron/root

Bạn có thể thiết lập cronjobs trên các máy chủ từ xa như sau:

#!/bin/bash
servers="srv1 srv2 srv3 srv4 srv5"
for i in $servers
  do
  echo "0 1 * * * /root/test.sh" | ssh $i " tee -a /var/spool/cron/root"
done

Trong Linux, vị trí mặc định của crontabtệp là /var/spool/cron/. Tại đây bạn có thể tìm thấy các crontabtập tin của tất cả người dùng. Bạn chỉ cần nối thêm mục cronjob của mình vào tệp người dùng tương ứng. Trong ví dụ trên, tệp crontab của người dùng root đang được gắn thêm một cronjob để chạy /root/test.shmỗi ngày vào lúc 1 giờ sáng.


Đó sẽ là /var/spool/cron/crontabs/roottrên Ubuntu.
Íhor Mé

17

Các tệp Crontab chỉ đơn giản là các tệp văn bản và như vậy có thể được xử lý như bất kỳ tệp văn bản nào khác. Mục đích của crontablệnh là làm cho việc chỉnh sửa các tệp crontab an toàn hơn. Khi chỉnh sửa thông qua lệnh này, tệp sẽ được kiểm tra lỗi và chỉ được lưu nếu không có.

crontab [path to file]có thể được sử dụng để chỉ định một crontab được lưu trữ trong một tệp. Giống như crontab -e, điều này sẽ chỉ cài đặt các tập tin nếu nó không có lỗi.

Do đó, một tập lệnh có thể trực tiếp ghi các tệp tab cron hoặc ghi chúng vào một tệp tạm thời và tải chúng bằng crontab [path to temp file]lệnh. Viết trực tiếp tiết kiệm phải viết một tập tin tạm thời, nhưng nó cũng tránh kiểm tra an toàn.


2
Đối với các noobs như tôi, lưu ý rằng đó là crontab [path to file].. Đây chắc chắn là lựa chọn tốt nhất cho tôi, vì nó cho phép mã dễ đọc hơn. Tôi sử dụng crontab để theo dõi bưu kiện và thay đổi hình nền máy tính của tôi với trạng thái. Khi tôi không mong đợi bưu kiện, nó không cần phải kiểm tra mỗi giờ. Đó là lý do tại sao tôi muốn tập lệnh tự động chỉnh sửa tần số cron.
Rasmus

1
@Rasmus Nghe có vẻ như một kịch bản tuyệt vời mà tôi thích có thể ăn cắp. Bất kỳ cơ hội chia sẻ thông qua một ý chính hoặc tương tự?
cledoux

8

(Tôi không có đủ danh tiếng để bình luận, vì vậy tôi đang thêm vào như một câu trả lời: vui lòng thêm nó dưới dạng nhận xét bên cạnh câu trả lời của anh ấy)

Một lớp lót của Joe Casadonte là hoàn hảo, ngoại trừ nếu bạn chạy cùng set -e, tức là nếu tập lệnh của bạn bị lỗi và nếu chưa có cronjobs. Trong trường hợp đó, một lớp lót sẽ KHÔNG tạo ra cronjob, nhưng sẽ KHÔNG dừng tập lệnh. Sự thất bại thầm lặng có thể rất sai lệch.

Lý do là crontab -ltrả về với 1mã trả về, khiến lệnh tiếp theo (the echo) không được thực thi ... do đó cronjob không được tạo. Nhưng vì chúng được thực thi như một quy trình con (vì dấu ngoặc đơn) nên chúng không dừng tập lệnh.

(Điều thú vị là nếu bạn chạy lệnh tương tự một lần nữa, nó sẽ làm việc: một khi bạn đã thực hiện crontab -một lần, crontab -lvẫn kết quả đầu ra không có gì, nhưng nó không trả về một lỗi nữa (bạn không nhận được no crontab for <user>thông điệp nữa) Vì vậy, sau này. echoĐược thực hiện và crontab được tạo ra)

Trong mọi trường hợp, nếu bạn chạy với set -e, dòng phải là:

(crontab -l 2>/dev/null || true; echo "*/5 * * * * /path/to/job -with args") | crontab -

Vâng, điều này thậm chí còn hoàn hảo hơn.
Yngve Sneen Lindal

7

Như một sự điều chỉnh cho những gợi ý crontab -l | crontab -: Điều này không hoạt động trên mọi hệ thống. Ví dụ: tôi đã phải thêm một công việc vào crontab gốc trên hàng tá máy chủ chạy SUSE phiên bản cũ (đừng hỏi tại sao). Các SUSE cũ đưa các dòng bình luận vào đầu ra của crontab -l, làm cho crontab -l | crontab -không phải là idempotent (Debian nhận ra vấn đề này trong trang quản trị crontab và vá phiên bản Vixie Cron của nó để thay đổi hành vi mặc định của crontab -l).

Để chỉnh sửa crontabs theo chương trình trên các hệ thống có crontab -lthêm nhận xét, bạn có thể thử các cách sau:

EDITOR=cat crontab -e > old_crontab; cat old_crontab new_job | crontab -

EDITOR=catyêu cầu crontab sử dụng catnhư một trình soạn thảo (không phải là vi mặc định thông thường), điều này không làm thay đổi tệp mà thay vào đó sao chép nó vào thiết bị xuất chuẩn. Điều này vẫn có thể thất bại nếu crontab -mong đợi đầu vào ở định dạng khác với crontab -eđầu ra. Đừng cố thay thế trận chung kết crontab -bằng crontab -e- nó sẽ không hoạt động.


4

Vâng /etc/crontabchỉ là một tập tin ascii vì vậy đơn giản nhất là chỉ

 echo "*/15 * * * *   root     date" >> /etc/crontab

sẽ thêm một công việc sẽ gửi email cho bạn cứ sau 15 phút. Điều chỉnh theo sở thích và kiểm tra thông qua grephoặc các phương tiện khác xem dòng đã được thêm vào để làm cho kịch bản của bạn không hoạt động.

Trên Ubuntu và cộng sự, bạn cũng có thể thả các tệp /etc/cron.*dễ thực hiện hơn và kiểm tra --- cộng với việc bạn không gây rối với các tệp cấu hình (hệ thống) như /etc/crontab.


1
Tôi nghĩ rằng crond về mặt kỹ thuật không bắt buộc phải giám sát các thay đổi đối với crontab, ngay cả trong thực tế, hầu hết các triển khai đều thực hiện, vì vậy tôi khuyên bạn nên gọi crontab -e sau đó để quảng cáo. crontab -e tôn vinh biến EDITOR nếu bộ nhớ phục vụ, do đó, đặt nó thành / bin / true vào lúc này chỉ nên buộc crontab được đọc lại.
Ulrich Schwarz

1
Đúng như vậy trên bất kỳ hệ thống Linux nào gần đây crond đều giám sát và chắc chắn nó hoạt động trên nền tảng đã nêu của OP.
Dirk Eddelbuettel

Chỉ khi bạn root và muốn tập lệnh chạy dưới quyền root. Điều đó có thể không được mong muốn trong trường hợp OP.
Keith

Không như vậy, tôi có rất nhiều mục không root trong / etc / crontab. Bạn 'chỉ cần' sudo để thêm vào tập tin. Dù sao, như tôi đã nói, cũng có /etc/cron.*/ nhưng bạn cũng cần phải root để viết ở đó.
Dirk Eddelbuettel

2

Dưới đây là cách sửa đổi cron một mục mà không cần chỉnh sửa trực tiếp tệp cron (được tán thành).

crontab -l -u <user> | sed 's/find/replace/g' | crontab -u <user> -

Nếu bạn muốn xóa một mục cron, hãy sử dụng mục này:

crontab -l -u <user> | sed '/find/d' | crontab -u <user> -

Tôi nhận ra đây không phải là những gì gaurav yêu cầu, nhưng tại sao không có tất cả các giải pháp ở một nơi?


1

Tôi đã viết một công cụ triển khai crontab bằng python: https://github.com/monklof/deploycron

pip install deploycron

Cài đặt crontab của bạn rất dễ dàng, điều này sẽ hợp nhất crontab vào crontab hiện có của hệ thống.

from deploycron import deploycron
deploycron(content="* * * * * echo hello > /tmp/hello")

1

Đây là một cách tiếp cận để tăng dần công việc định kỳ:

  ssh USER_NAME@$PRODUCT_IP nohup "echo '*/2 * * * * ping -c2 PRODUCT_NAME.com >> /var/www/html/test.html' | crontab -u USER_NAME -"
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.