Tôi cần khả năng chạy một tập lệnh PHP 20 lần một ngày vào những thời điểm hoàn toàn ngẫu nhiên. Tôi cũng muốn nó chỉ chạy từ 9 giờ sáng đến 11 giờ tối.
Tôi đã quen với việc tạo cron job trong linux.
Tôi cần khả năng chạy một tập lệnh PHP 20 lần một ngày vào những thời điểm hoàn toàn ngẫu nhiên. Tôi cũng muốn nó chỉ chạy từ 9 giờ sáng đến 11 giờ tối.
Tôi đã quen với việc tạo cron job trong linux.
Câu trả lời:
Nếu tôi hiểu những gì bạn đang tìm kiếm, bạn sẽ cần phải làm điều gì đó hơi lộn xộn, chẳng hạn như có một công việc cron chạy một tập lệnh bash ngẫu nhiên thời gian chạy ... Một cái gì đó như thế này:
crontab:
0 9 * * * /path/to/bashscript
và trong / path / to / bashscript:
#!/bin/bash
maxdelay=$((14*60)) # 14 hours from 9am to 11pm, converted to minutes
for ((i=1; i<=20; i++)); do
delay=$(($RANDOM%maxdelay)) # pick an independent random delay for each of the 20 runs
(sleep $((delay*60)); /path/to/phpscript.php) & # background a subshell to wait, then run the php script
done
Một vài lưu ý: cách tiếp cận này hơi lãng phí tài nguyên vì nó kích hoạt 20 quy trình nền lúc 9 giờ sáng, mỗi quy trình chờ khoảng một số phút ngẫu nhiên (lên đến 14 giờ, tức 11 giờ tối), sau đó khởi chạy tập lệnh php và lối thoát hiểm. Ngoài ra, vì nó sử dụng một số phút ngẫu nhiên (không phải giây), thời gian bắt đầu không hoàn toàn ngẫu nhiên như chúng có thể. Nhưng $ RANDOM chỉ tăng lên đến 32.767 và có 50.400 giây trong khoảng thời gian từ 9 giờ sáng đến 11 giờ tối, sẽ phức tạp hơn một chút nếu ngẫu nhiên các giây. Cuối cùng, vì thời gian bắt đầu là ngẫu nhiên và độc lập với nhau, nên có thể (nhưng không có khả năng cao) rằng hai hoặc nhiều trường hợp của tập lệnh sẽ được bắt đầu đồng thời.
((maxdelay = 14 * 60))
hoặc ((delay = $RANDOM % maxdelay))
). Đối sleep
số vẫn cần theo cách bạn có (mặc dù bạn có thể thêm dấu cách, nếu muốn).
sleep $[ ( $RANDOM % 60 ) + 1 ]s && some_script.sh
Vâng, vâng, câu hỏi đã hơn một năm, nhưng có lẽ tôi có thể bổ sung một số điều hữu ích:
Làm thế nào để thu thập một thứ gì đó ở một khoảng thời gian bù trừ ngẫu nhiên 20 lần một ngày trong khoảng thời gian từ 9 giờ sáng đến 11 giờ tối? Điều đó khá phức tạp trong cron, bởi vì bạn đang chia 14 giờ cho 20 lần thực hiện. Tôi không thích các câu trả lời khác cho lắm vì chúng yêu cầu viết một tập lệnh trình bao bọc bash cho tập lệnh php của bạn.
Tuy nhiên, nếu bạn cho phép tôi tự do giảm giới hạn thời gian và tần suất xuống 13 lần trong khoảng thời gian từ 8:30 sáng đến 11:09 tối, thì điều này có thể thực hiện thủ thuật và tất cả đều nằm trong giới hạn của crontab của bạn:
30 8-21/* * * * sleep ${RANDOM:0:2}m ; /path/to/script.php
$ {RANDOM: 3: 2} sử dụng $ RANDOM của bash mà những người khác đã đề cập ở trên, nhưng thêm tính năng cắt mảng bash. Vì các biến cơ sở không được định kiểu, nên số 16 bit có dấu giả ngẫu nhiên sẽ bị cắt ngắn thành 2 trong số 5 chữ số thập phân đầu tiên của nó, cung cấp cho bạn một lớp lót ngắn gọn để trì hoãn cronjob của bạn từ 10 đến 99 phút (mặc dù phân phối có xu hướng 10 đến 32).
Những điều sau đây cũng có thể phù hợp với bạn, nhưng tôi thấy nó "ít ngẫu nhiên hơn" vì một số lý do (có lẽ Định luật Benford được kích hoạt bằng cách điều chế các số giả ngẫu nhiên. Này, tôi không biết, tôi không thích toán học ... Đổ lỗi cho nó trên bash!):
30 8-21/* * * * sleep $[RANDOM\%90]m ; /path/to/script.php
Bạn cần kết xuất mô-đun như '\%' ở trên vì cron (tốt, ít nhất là Linux 'vixie-cron') kết thúc dòng khi nó gặp phải '%' không thoát.
Có thể bạn có thể nhận được 7 lần thực thi tập lệnh còn lại trong đó bằng cách thêm một dòng khác với phạm vi 7 giờ khác. Hoặc nới lỏng hạn chế chạy trong khoảng thời gian từ 3 giờ sáng đến 11 giờ đêm.
$[(RANDOM/368)+10]
?
$((RANDOM % 90 + 10))
Kiểm tra:for i in {0..9999}; do echo $((RANDOM % 90 + 10)); done | sort | uniq -c
$RANDOM
: sleep $(( $(od -N1 -tuC -An /dev/urandom) \% 90 ))m
.
crontab
đang sử dụng bash
trước khi sử dụng $RANDOM
. Nếu bạn có vixie-cron
(dường như là trường hợp của tôi trên Ubuntu), thì bạn có thể thêm SHELL=/bin/bash
vào đầu trang. Có rất nhiều lựa chọn thay thế cho các phiên bản cron khác tại đây: superuser.com/a/264541/260350
crontab: errors in crontab file, can't install. Do you want to retry the same edit?
sự giúp đỡ
Vì vậy, tôi đang sử dụng phần sau để chạy lệnh từ 1AM đến 330AM
0 1 * * * perl -le 'sleep rand 9000' && *command goes here*
Điều đó đã được chăm sóc các nhu cầu ngẫu nhiên của tôi cho tôi. Đó là 9000 giây == 150 phút == 2,5 giờ
Cron cung cấp một RANDOM_DELAY
biến. Xem crontab(5)
chi tiết.
Biến RANDOM_DELAY cho phép trì hoãn việc khởi động công việc theo số phút ngẫu nhiên với giới hạn trên do biến chỉ định.
Điều này thường thấy trong các anacron
công việc, nhưng cũng có thể hữu ích trong a crontab
.
Bạn có thể cần phải cẩn thận với điều này nếu bạn có một số công việc chạy ở mức độ chi tiết tốt (phút) và những công việc khác thì thô.
RANDOM_DELAY
được thiết lập một lần và không đổi trong toàn bộ thời gian chạy của daemon.
RANDOM_DELAY
lá cờ là tính năng của cronie-crond trong khi Ubuntu vẻ là đang chạy vixie-cron
mà thiếu lá cờ này.
Suy nghĩ đầu tiên của tôi là tạo ra một công việc cron khởi chạy 20 công việc được lên lịch ngẫu nhiên. Các at
tiện ích (http://unixhelp.ed.ac.uk/CGI/man-cgi?at) được sử dụng để thực hiện các lệnh tại thời gian nhất định.
Tôi đã kết thúc sử dụng sleep $(( 1$(date +%N) % 60 )) ; dostuffs
(tương thích với bash & sh)
Tiền tố 1 là buộc NON cơ số 8 diễn giải ngày +% N (ví dụ: 00551454)
Đừng quên thoát% bằng cách sử dụng \% trong tệp crontab
* * * * * nobody sleep $(( 1$(date +\%N) \% 60 )) ; dostuffs
date
(điều này có thể bạn thực hiện trên hầu hết các Linux, nhưng không phải trên Busybox, MacOS tiêu chuẩn hoặc nhiều nền tảng khác có nguồn gốc từ BSD).
Giải pháp của al-x không hoạt động đối với tôi vì các lệnh crontab không được thực hiện trong bash nhưng trong sh tôi đoán. Công việc là gì:
30 8 * * * bash -c "sleep $[RANDOM\%90]m" ; /path/to/script.py
$[ ... ]
là cú pháp không được chấp nhận kể từ waaaay trở lại; đối với bất kỳ thứ gì từ thiên niên kỷ này, bạn sẽ thích $((RANDOM\%90))m
cú pháp tương thích với POSIX (nhưng tất nhiên RANDOM
vẫn chỉ là Bash).
at -f [file] [timespec]
hoặc là
echo [command] | at [timespec]
hoặc là
at [timespec]
... và đặc điểm kỹ thuật tương tác như script
ghi âm của.
Lúc chạy văn bản cung cấp trên stdin hoặc trong tệp được chỉ định bởi -f [file]
.
Đây là [timespec]
ngữ pháp . Nó có thể là một cái gì đó như:
0100
, 2359
,1620
now + 10 minutes
2071-05-31 - 5 hours 12 minutes UTC
Nếu bạn chỉ định rõ ràng múi giờ, một số phiên bản của timepec có thể chỉ cho phép UTC
đối số múi giờ tùy chọn.
cat script.sh | at now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes
at -f script.sh now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes
Bạn có thể kiểm tra phân tích cú pháp bash bằng cách chờ xử lý trước echo
và thoát khỏi |
(đường ống).
echo cat script.sh \| at now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes
echo at -f script.sh now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes
Để xem các công việc đã lên lịch, sử dụng atq
và nội dung công việc (môi trường, thiết lập và lệnh / script) với at -c [jobid]
.
Hệ thống là một phần của cron và dấu nhắc tương tác thực sự nắm bắt toàn bộ trạng thái hiện tại của trình bao, vì vậy bạn có thể chạy các lệnh mà không cần chỉ định đường dẫn tuyệt đối.
Đối với những người đã truy cập vào googled ở đây:
Nếu bạn đang sử dụng anacron (máy tính để bàn và máy tính xách tay Ubuntu) thì bạn có thể chỉnh sửa
/etc/anacrontab
và thêm vào
RANDOM_DELAY=XX
Trong đó XX là số phút bạn muốn trì hoãn công việc cơ bản.
Anacron giống như cron nhưng nó không mong đợi máy tính của bạn ở dạng 24x7 (như máy tính xách tay của chúng tôi) và sẽ chạy các tập lệnh mà nó đã bỏ lỡ do hệ thống bị lỗi.
Bạn có thể thử với ví dụ này để sử dụng thời gian ngẫu nhiên trước khi thực hiện lệnh:
#!/bin/bash
# start time
date +"%H:%M:%S"
# sleep for 5 seconds
sleep $(shuf -i 1-25 -n 1)
# end time
date +"%H:%M:%S"
Còn việc tạo script viết lại crontab mỗi ngày thì sao?
Tôi nhận ra đó là một chuỗi cũ hơn, nhưng tôi muốn thêm một thứ liên quan đến giá trị ngẫu nhiên mà tôi sử dụng nhiều. Thay vì sử dụng biến $ RANDOM với phạm vi cố định và giới hạn, tôi thường tạo các giá trị ngẫu nhiên phạm vi tùy ý trong trình bao với
dd if=/dev/urandom bs=4 count=1 2>/dev/null | od -N4 -t u4 -A none
vì vậy bạn có thể làm, chẳng hạn như
FULLRANDOM=$(dd if=/dev/urandom bs=4 count=1 2>/dev/null | od -N4 -t u4 -A none)
và khắc phục một số hạn chế đã được thảo luận trong chủ đề này.
~$info dd
và tôi có thể hiểu những gì đang xảy ra ở phía bên trái của |
, nhưng không thể hiểu được phía bên phải. Vì vậy, đối với tôi và những người khác quan tâm đến việc overcoming some restrictions
tạo ra giá trị ngẫu nhiên, tại sao không dành một chút thời gian để giải thích RHS và đưa ra một quảng cáo mạnh mẽ hơn để sử dụng phương pháp của bạn. Sự giải thích sâu sắc vừa làm cho mọi người thoải mái với quy trình bạn đề xuất và lợi ích của nó Cảm ơn.