Tôi có thể chạy một công việc định kỳ thường xuyên hơn mỗi phút không?


44

Có thể chạy một công việc định kỳ cứ sau 30 giây mà không cần lệnh ngủ?


4
Ý định của bạn là gì? Cron là công cụ phù hợp để sử dụng cho việc này?
Manuel Faux

Câu hỏi hay.
Preet Sangha

Chẳng hạn, tôi hiện đang sử dụng cron để thay đổi ảnh nền của máy tính để bàn, để tránh các hạn chế của trình chuyển đổi ảnh nền gốc (không đi sâu vào các thư mục con). Nếu tôi muốn chuyển đổi thường xuyên hơn một lần mỗi phút, tôi sẽ chạy vào giới hạn cron này. (mặc dù trình chuyển đổi bg bản địa có cùng giới hạn)
donquixote

Câu trả lời:


36

Nếu nhiệm vụ của bạn cần chạy thường xuyên, cron là công cụ sai. Ngoài thực tế là nó đơn giản sẽ không khởi động các công việc thường xuyên, bạn cũng có thể gặp một số vấn đề nghiêm trọng nếu công việc mất nhiều thời gian hơn so với khoảng thời gian giữa các lần khởi chạy. Viết lại nhiệm vụ của bạn để daemonize và chạy liên tục, sau đó khởi chạy nó từ cron nếu cần thiết (trong khi đảm bảo rằng nó sẽ không khởi động lại nếu nó đang chạy).


18
Phần "bạn cũng có nguy cơ gặp phải một số vấn đề nghiêm trọng nếu công việc mất nhiều thời gian hơn so với khoảng thời gian giữa các lần khởi chạy." là không đúng sự thật và nếu nó được áp dụng như nhau cho các công việc chạy cứ sau 5 phút, mỗi giờ hoặc mỗi tháng cho vấn đề đó. Vấn đề đó có giải pháp (sử dụng pidfile hoặc bất cứ điều gì và kiểm tra xem công việc đã chạy chưa trước khi chạy nó). Vì vậy, vấn đề là cron chỉ không cho phép tần số đó, nhưng không đúng khi nói rằng có một cái gì đó thực sự sai trong việc thực hiện một nhiệm vụ cứ sau chưa đầy một phút.
matteo

2
Ý tôi là nếu bạn không sử dụng pidfile. Nếu công việc của bạn chạy cứ sau X phút và mất hơn X phút để hoàn thành, bạn sẽ kết thúc với công việc sắp xếp. Nếu công việc của bạn cũng bị giới hạn bởi một số loại tài nguyên (CPU, băng thông mạng / đĩa, v.v.), thì việc chạy nhiều hơn một lúc sẽ khiến bạn mất nhiều thời gian hơn để hoàn thành, và cuối cùng máy tính của bạn sẽ biến thành một mớ hỗn độn.
duskwuff

2
Bạn có thể sử dụng run-oneđể đảm bảo chương trình / thậm chí tập lệnh PHP không bắt đầu phiên bản trùng lặp. sudo apt-get install run-onevà gọi nó bằngrun-one <normal command>
kouton

3
Khi câu trả lời tiếp tục hiển thị, nó rất có thể, mặc dù có một chút hackish. Tại sao BẠN ĐANG LÀM SAU !!!! câu trả lời được chấp nhận ở đây, khi nó không trả lời câu hỏi nào cả?
Ai đó

@Mantriur Bởi vì tác giả của câu hỏi thấy nó hữu ích và đánh dấu nó là câu trả lời được chấp nhận? :) Nhưng nghiêm túc, mặc dù, bạn đã tự mình xác định vấn đề: nhiều câu trả lời đương thời khác đề xuất các giải pháp hackish sẽ không khôn ngoan khi sử dụng trong một hệ thống sản xuất. (Ngoài ra, hãy nhớ rằng một số câu trả lời khác chỉ xuất hiện nhiều năm sau khi câu hỏi được hỏi, vì vậy chúng chưa có sẵn để chấp nhận!)
duskwuff

37

Ứng cử viên cho việc lạm dụng sáng tạo nhất một lệnh Linux:

nohup watch -n 30 --precise yourprog >/dev/null &

Nếu yourprogbao gồm:

date +%M.%S.%N >> yourprog.out

sau đó yourprog.outcó thể trông giống như:

50.51.857291267
51.21.840818353
51.51.840910204
52.21.840513307
52.51.842455224
53.21.841195858
53.51.841407587
54.21.840629676

cho thấy một mức độ chính xác khá tốt.

Dưới đây là một lời giải thích về các phần của lệnh:

  • nohup- Điều này giữ cho lệnh theo sau nó, watchtrong trường hợp này, không thoát khi thiết bị đầu cuối thoát.
  • watch- Chương trình này chạy một lệnh nhiều lần. Thông thường, màn hình đầu ra đầu tiên từ lệnh được hiển thị mỗi lần watchchạy lệnh.
  • -n 30- Khoảng thời gian để chạy lệnh. Trong trường hợp này cứ sau ba mươi giây.
  • --precise- Không có tùy chọn này, watchchạy lệnh sau khoảng thời gian vài giây. Với nó, mỗi lần bắt đầu lệnh bắt đầu vào khoảng nếu có thể. Nếu tùy chọn này không được chỉ định trong ví dụ, thời gian sẽ có sau và hơn 30 giây mỗi lần do thời gian cần thiết để khởi chạy và thực thi lệnh ( yourprog).
  • yourprog- Chương trình hoặc dòng lệnh watchđể thực thi. Nếu dòng lệnh chứa các ký tự đặc biệt cho trình bao (ví dụ: dấu cách hoặc dấu chấm phẩy), nó sẽ cần được trích dẫn.
  • >/dev/null- Lớn hơn chuyển hướng đầu ra của lệnh đang được chạy bởi watchmột tệp , /dev/null. Tập tin đó loại bỏ bất kỳ dữ liệu được ghi vào nó. Điều này ngăn đầu ra không được ghi vào màn hình hoặc, vì nohupđang được sử dụng, nó ngăn đầu ra được gửi đến một tệp được gọi nohup.out.
  • &- watchLệnh được chạy trong nền và điều khiển được trả về thiết bị đầu cuối hoặc tiến trình cha.

Lưu ý rằng nohup, việc chuyển hướng đầu ra và &toán tử điều khiển nền không cụ thể watch.

Dưới đây là một lời giải thích về yourprogkịch bản ví dụ :

  • date- Xuất ra ngày và / hoặc thời gian hiện tại. Nó cũng có thể thiết lập chúng.
  • +%M.%S.%N- Điều này chỉ định định dạng đầu ra dateđể sử dụng. %Mlà phút hiện tại, %Slà giây hiện tại và %Nlà nano giây hiện tại.
  • >> yourprog.out- Điều này chuyển hướng đầu ra của datelệnh đến một tệp được gọi yourprog.out. Lớn hơn gấp đôi so với nguyên nhân khiến đầu ra được gắn vào tệp trên mỗi lệnh gọi thay vì nội dung trước đó được ghi đè.

Chỉnh sửa :

Có thể một thứ khác có thể bị lạm dụng (hoặc có lẽ đó là một cách sử dụng hợp pháp) là bộ định thời hệ thống.

Xem systemd / Timers dưới dạng thay thế cronbộ định thời Cron so với systemd .

Tôi sẽ cố gắng đăng một ví dụ sớm.


6
Tôi đang cho +1 cho má thuần khiết
Matt Simmons

2
Sẽ rất tốt để có thêm một chút giải thích với câu trả lời này. Lệnh nohup là mới đối với tôi. Internet cho tôi biết đó là bỏ qua tín hiệu gác máy. Mà vẫn khiến tôi bối rối.
donquixote

2
@donquixote: Điều quan trọng là phải nhận ra rằng toàn bộ câu lệnh trong câu trả lời của tôi không phải là điều nên làm, do đó việc sử dụng từ "sử dụng sai". Tuy nhiên, để làm rõ mọi thứ cho bạn một chút vì có những kỹ thuật hữu ích bao gồm tôi sẽ cố gắng mô tả một vài. Các &nguyên nhân khiến lệnh chạy trong nền, trả lại quyền điều khiển cho dấu nhắc lệnh ngay lập tức. Sử dụng nohuplệnh làm cho quá trình nền (trong trường hợp này watch) bỏ qua tín hiệu gác máy được gửi khi thoát khỏi vỏ như khi bạn đóng thiết bị đầu cuối. ...
Dennis Williamson

1
... Chuyển hướng đầu ra bằng cách sử dụng >/dev/nulllàm cho đầu ra bị loại bỏ và ngăn việc tạo một nohup.outtệp sẽ được tạo khi đầu ra tiêu chuẩn là một thiết bị đầu cuối.
Dennis Williamson

1
@donquixote: Không chỉ 30 giây kể từ bây giờ, cứ sau 30 giây. Phần còn lại là để nó chạy không giám sát trong nền để giống như cron hơn. Nếu bạn muốn sử dụng sleep, bạn sẽ cần phải viết một vòng lặp để quá trình lặp lại ( watchđiều này lặp lại cho bạn, như vậy cron). Bạn vẫn sẽ cần nohup&. Một vấn đề được thêm vào sleepsẽ là thời gian trôi. Các --precisetùy chọn watchtránh điều này. Không có nó hoặc khi sử dụng sleeptrong một vòng lặp, khoảng thời gian có thời gian để các lệnh hoặc tập lệnh chạy được thêm vào nó để mỗi lần chạy được muộn hơn và muộn hơn ...
Dennis Williamson

13

Cron được thiết kế để thức dậy mỗi phút, vì vậy không thể làm điều đó mà không có một số hack, ví dụ như giấc ngủ như bạn đã đề cập.


10
* * * * * /path/to/program
* * * * * sleep 30; /path/to/program

Đừng quên viết một cái gì đó vào chương trình của bạn để nó thoát ra nếu một phiên bản trước đó đang chạy.

#!/bin/sh

if ln -s "pid=$$" /var/pid/myscript.pid; then
  trap "rm /var/pid/myscript.pid" 0 1 2 3 15
else
  echo "Already running, or stale lockfile." >&2
  exit 1
fi

Tất nhiên, điều này vẫn để lại một cơ hội rất nhỏ cho thất bại, vì vậy hãy tìm kiếm google để có giải pháp tốt hơn cho môi trường của bạn.


nó đã được hỏi:without a sleep command
philippe

10
Những khách truy cập khác tìm thấy câu hỏi này không quan tâm nếu lệnh ngủ được sử dụng :)
donquixote

8

Bạn có thể làm điều này với phần mềm của bên thứ ba.

Một lựa chọn đã làm việc tốt với tôi là cron thường xuyên

Nó cho phép độ chính xác đến mili giây và nó cung cấp cho bạn tùy chọn trì hoãn thực hiện tiếp theo cho đến khi thoát hiện tại ..


1
Cron thường xuyên cũng đã làm việc tốt cho chúng tôi và cung cấp năng lượng cho nhiều hệ thống sản xuất của chúng tôi. Chúng tôi chưa bao giờ có vấn đề với nó.
Homer6

2

Tôi có một vài mối quan tâm:

. Điều. Tùy thuộc vào kịch bản, có thể có một số can thiệp đáng kể ở đây. Do đó, mã hóa trong một tập lệnh như vậy nên chứa một số mã để đảm bảo rằng chỉ có một phiên bản của tập lệnh đã cho đang chạy cùng một lúc.

(2) Kịch bản có thể có nhiều chi phí hoạt động và tiêu tốn nhiều tài nguyên hệ thống hơn bạn muốn. Điều này đúng nếu bạn đang cạnh tranh với rất nhiều hoạt động hệ thống khác.

Do đó, như một poster đã đặt nó, trong trường hợp này, tôi nghiêm túc xem xét việc đưa một trình nền chạy với các quy trình bổ sung để đảm bảo nó vẫn chạy nếu nó có tầm quan trọng quan trọng đối với hoạt động của bạn.


1

giải pháp đơn giản và yêu thích của tôi cho nhiệm vụ này:

mục nhập:
* * * * * flock -w0 /path/to/script /path/to/script

kịch bản:
while true;do echo doing something; sleep 10s;done

lười thay thế: :)

* * * * * flock -w0 /path/to/log watch -n 10 echo doing >> /path/to/log

hoặc là

* * * * * flock -w0 /path/to/log watch -n 10 /path/to/script

ưu

  • sử dụng flocklệnh tránh chạy tập lệnh theo nhiều trường hợp cùng một lúc. Nó có thể rất quan trọng trong hầu hết các trường hợp.
  • flockwatchcác lệnh có sẵn trên hầu hết các bản cài đặt Linux

khuyết điểm

  • dừng loại "Dịch vụ" này cần hai bước
    • bình luận ra mục nhập
    • giết tập lệnh hoặc watchlệnh

2
Ai đó có thể vui lòng giải thích điều này với một newbie linux - với ưu và nhược điểm không? Cảm ơn ..
a20

@asvany Tôi nghĩ rằng tôi thích giải pháp này nhưng là a20, bạn có thể đăng một số lời giải thích cho Linux "xanh" không? ty.
JoelAZ

0

Một giải pháp, nếu đó là cho kịch bản của riêng bạn hoặc nếu bạn có thể gói nó:

  1. Nhận và nhớ thời gian bắt đầu.
  2. Nếu một tệp khóa mà bạn sẽ chạm vào sau đó, sẽ xuất hiện và tập lệnh không chạy trong 60 giây, đợi một giây và kiểm tra lại. (ví dụ: trong khi / ngủ) *
  3. Nếu tệp khóa vẫn còn sau 60 giây, hãy thoát với cảnh báo khóa cũ.
  4. Chạm vào tập tin khóa.
  5. Mặc dù tập lệnh không chạy trong 60 giây, hãy lặp lại tác vụ thực tế của bạn với thời lượng ngủ mong muốn.
  6. Xóa tập tin khóa.
  7. Thêm như cron tối thiểu.
  8. Bob là chú của bạn.

Ít đau đầu hơn xây dựng và giám sát một daemon.

* Nếu bạn đang sử dụng PHP, hãy nhớ Clearstatcache ().

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.