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ủ?
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ủ?
Câu trả lời:
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).
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-one
và gọi nó bằngrun-one <normal command>
Ứ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 yourprog
bao gồm:
date +%M.%S.%N >> yourprog.out
sau đó yourprog.out
có 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ó, watch
trong 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 watch
chạ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, watch
chạ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 watch
mộ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
.&
- watch
Lệ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ề yourprog
kị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. %M
là phút hiện tại, %S
là giây hiện tại và %N
là nano giây hiện tại.>> yourprog.out
- Điều này chuyển hướng đầu ra của date
lệ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ế cron và bộ định thời Cron so với systemd .
Tôi sẽ cố gắng đăng một ví dụ sớm.
&
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 nohup
lệ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. ...
>/dev/null
làm cho đầu ra bị loại bỏ và ngăn việc tạo một nohup.out
tệp sẽ được tạo khi đầu ra tiêu chuẩn là một thiết bị đầu cuối.
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
và &
. Một vấn đề được thêm vào sleep
sẽ là thời gian trôi. Các --precise
tùy chọn watch
tránh điều này. Không có nó hoặc khi sử dụng sleep
trong 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 ...
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.
* * * * * /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.
without a sleep command
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 ..
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.
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
* * * * * 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
flock
lệ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.flock
và watch
các lệnh có sẵn trên hầu hết các bản cài đặt Linuxwatch
lệnhMộ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ó:
Í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 ().