ฉันต้องการความสามารถในการเรียกใช้สคริปต์ PHP 20 ครั้งต่อวันในเวลาสุ่มอย่างสมบูรณ์ ฉันยังต้องการให้มันทำงานระหว่าง 9.00 น. - 23.00 น. เท่านั้น
ฉันคุ้นเคยกับการสร้างงาน cron ใน linux
ฉันต้องการความสามารถในการเรียกใช้สคริปต์ PHP 20 ครั้งต่อวันในเวลาสุ่มอย่างสมบูรณ์ ฉันยังต้องการให้มันทำงานระหว่าง 9.00 น. - 23.00 น. เท่านั้น
ฉันคุ้นเคยกับการสร้างงาน cron ใน linux
คำตอบ:
ถ้าฉันเข้าใจสิ่งที่คุณกำลังมองหาคุณจะต้องทำอะไรบางอย่างที่ยุ่งเหยิงเช่นมีงาน cron ที่เรียกใช้สคริปต์ทุบตีที่สุ่มเวลารัน ... อะไรทำนองนี้:
crontab:
0 9 * * * /path/to/bashscript
และใน / 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
ข้อสังเกตบางประการ: วิธีนี้เป็นการสิ้นเปลืองทรัพยากรเล็กน้อยเนื่องจากจะทำให้กระบวนการพื้นหลัง 20 กระบวนการทำงานในเวลา 9.00 น. ซึ่งแต่ละกระบวนการรอเป็นเวลาสุ่มเป็นเวลาหลายนาที (สูงสุด 14 ชั่วโมงเช่น 23.00 น.) จากนั้นเปิดสคริปต์ php และ ออก นอกจากนี้เนื่องจากใช้จำนวนนาทีแบบสุ่ม (ไม่ใช่วินาที) เวลาเริ่มต้นจึงไม่สุ่มเท่าที่ควร แต่ $ RANDOM จะสูงถึง 32,767 เท่านั้นและมีเวลา 50,400 วินาทีระหว่าง 9.00 น. ถึง 23.00 น. การสุ่มวินาทีจะซับซ้อนกว่าเล็กน้อยเช่นกัน ในที่สุดเนื่องจากเวลาเริ่มต้นเป็นแบบสุ่มและเป็นอิสระจากกันจึงเป็นไปได้ (แต่ไม่น่าจะเป็นไปได้มากนัก) ที่สคริปต์สองอินสแตนซ์หรือมากกว่านั้นจะเริ่มต้นพร้อมกัน
((maxdelay = 14 * 60))
หรือ((delay = $RANDOM % maxdelay))
) sleep
อาร์กิวเมนต์ยังคงต้องการที่จะเป็นวิธีการที่คุณมีมัน (แม้ว่าคุณสามารถเพิ่มช่องว่างถ้าต้องการ)
sleep $[ ( $RANDOM % 60 ) + 1 ]s && some_script.sh
ใช่คำถามนี้มีอายุมากกว่าหนึ่งปีแล้ว แต่ฉันอาจจะเพิ่มสิ่งที่มีประโยชน์:
จะ cron บางสิ่งบางอย่างโดยสุ่มชดเชย 20 ครั้งต่อวันระหว่าง 9.00 น. ถึง 23.00 น. นั่นค่อนข้างยุ่งยากภายใน cron เพราะคุณหาร 14 ชั่วโมงด้วย 20 ครั้งในการดำเนินการ ฉันไม่ชอบคำตอบอื่น ๆ มากนักเพราะต้องเขียนสคริปต์ bash wrapper สำหรับสคริปต์ php ของคุณ
อย่างไรก็ตามหากคุณยอมให้ฉันมีอิสระในการลดเวลาและการ จำกัด ความถี่เป็น 13 ครั้งระหว่าง 08:30 น. ถึง 23:09 น. นี่อาจเป็นกลอุบายและทั้งหมดนี้อยู่ในขอบเขตของ crontab ของคุณ:
30 8-21/* * * * sleep ${RANDOM:0:2}m ; /path/to/script.php
$ {RANDOM: 3: 2} ใช้ $ RANDOM ของ bash ที่คนอื่นพูดถึงข้างต้น แต่เพิ่มการแบ่งส่วน bash array เนื่องจากตัวแปร bash ไม่ได้ถูกพิมพ์ตัวเลข 16 บิตที่ลงชื่อแบบสุ่มหลอกจะถูกตัดทอนให้เหลือ 2 หลักแรกจากทศนิยม 5 หลักทำให้คุณมีหนึ่งซับสั้น ๆ สำหรับการหน่วงเวลา cronjob ระหว่าง 10 ถึง 99 นาที (แม้ว่าการแจกแจงจะเอนเอียงไปทาง 10 ถึง 32)
สิ่งต่อไปนี้อาจใช้ได้ผลสำหรับคุณเช่นกัน แต่ฉันพบว่ามัน "สุ่มน้อยกว่า" ด้วยเหตุผลบางประการ (บางทีกฎของ Benford อาจเกิดจากการปรับตัวเลขสุ่มหลอกเฮ้ฉันไม่รู้ฉันเข้าใจคณิตศาสตร์ ... ทุบตี!):
30 8-21/* * * * sleep $[RANDOM\%90]m ; /path/to/script.php
คุณต้องแสดงโมดูลัสเป็น '\%' ด้านบนเนื่องจาก cron (อย่างน้อยก็คือ 'vixie-cron' ของ Linux) จะยุติบรรทัดเมื่อพบ '%' ที่ไม่มีค่า Escape
บางทีคุณอาจได้รับการดำเนินการสคริปต์ที่เหลืออีก 7 รายการโดยการเพิ่มอีกบรรทัดด้วยช่วง 7 ชั่วโมงอีกครั้ง หรือผ่อนคลายข้อ จำกัด ของคุณให้วิ่งระหว่าง 03.00 น. ถึง 23.00 น.
$[(RANDOM/368)+10]
ล่ะ?
$((RANDOM % 90 + 10))
ทดสอบ: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
มีการใช้ก่อนที่คุณใช้bash
$RANDOM
หากคุณมีvixie-cron
(ดูเหมือนจะเป็นกรณีของฉันบน Ubuntu) คุณสามารถเพิ่มSHELL=/bin/bash
ไปที่ด้านบน มีทางเลือกเพิ่มเติมสำหรับ cron เวอร์ชันอื่นที่นี่: superuser.com/a/264541/260350
crontab: errors in crontab file, can't install. Do you want to retry the same edit?
ขอความช่วยเหลือ
ดังนั้นฉันใช้สิ่งต่อไปนี้เพื่อเรียกใช้คำสั่งระหว่าง 1AM ถึง 330AM
0 1 * * * perl -le 'sleep rand 9000' && *command goes here*
นั่นดูแลความต้องการสุ่มของฉันสำหรับฉัน นั่นคือ 9000 วินาที == 150 นาที == 2.5 ชั่วโมง
Cron เสนอRANDOM_DELAY
ตัวแปร ดูcrontab(5)
รายละเอียด
ตัวแปร RANDOM_DELAY ช่วยให้การเริ่มต้นงานล่าช้าโดยการสุ่มจำนวนนาทีโดยมีขีด จำกัด สูงสุดที่ตัวแปรระบุไว้
สิ่งนี้พบเห็นได้ทั่วไปในanacron
งาน แต่ยังมีประโยชน์ในไฟล์crontab
.
คุณอาจต้องระวังเรื่องนี้หากคุณมีงานบางอย่างที่ทำงานด้วยความละเอียด (นาที) และงานอื่น ๆ ที่มีความหยาบ
RANDOM_DELAY
สร้างขึ้นครั้งเดียวและคงที่สำหรับรันไทม์ทั้งหมดของ daemon
ความคิดแรกของฉันคือการสร้างงาน cron หนึ่งงานโดยเปิด 20 งานแบบสุ่มที่กำหนดไว้ในงาน at
ยูทิลิตี้ (http://unixhelp.ed.ac.uk/CGI/man-cgi?at) จะใช้สำหรับการรันคำสั่งในเวลาที่กำหนด
ฉันใช้ sleep $(( 1$(date +%N) % 60 )) ; dostuffs
(เข้ากันได้กับ bash & sh)
คำนำหน้า 1 คือการบังคับให้ NON ฐาน 8 ตีความวันที่ +% N (เช่น 00551454)
อย่าลืมหนี% โดยใช้ \% ในไฟล์ crontab
* * * * * nobody sleep $(( 1$(date +\%N) \% 60 )) ; dostuffs
date
(ซึ่งคุณอาจทำบน Linux ส่วนใหญ่ แต่ไม่ใช่บน Busybox, MacOS มาตรฐานหรือแพลตฟอร์มที่ได้รับ BSD อื่น ๆ )
โซลูชันของ al-x ไม่ได้ผลสำหรับฉันเนื่องจากคำสั่ง crontab ไม่ได้ดำเนินการใน bash แต่ฉันเดาว่าใน sh งานคืออะไร:
30 8 * * * bash -c "sleep $[RANDOM\%90]m" ; /path/to/script.py
$[ ... ]
เป็นไวยากรณ์ที่เลิกใช้แล้วเนื่องจาก waaaay กลับมา สำหรับทุกสิ่งจากสหัสวรรษนี้คุณต้องการ$((RANDOM\%90))m
ไวยากรณ์ที่เข้ากันได้กับ POSIX (แต่แน่นอนว่าRANDOM
ยังคงเป็น Bash เท่านั้น)
at -f [file] [timespec]
หรือ
echo [command] | at [timespec]
หรือ
at [timespec]
... และข้อกำหนดเชิงโต้ตอบเช่นscript
การบันทึก
ที่รันข้อความระบุบนstdinหรือในไฟล์ที่ระบุโดย-f [file]
.
นี่คือไวยากรณ์[timespec]
อาจเป็นสิ่งที่ต้องการ:
0100
, 2359
,1620
now + 10 minutes
2071-05-31 - 5 hours 12 minutes UTC
หากคุณระบุเขตเวลาอย่างชัดเจน ไทม์สเปคบางเวอร์ชันอาจอนุญาตเฉพาะUTC
อาร์กิวเมนต์เขตเวลาที่ไม่บังคับ
cat script.sh | at now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes
at -f script.sh now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes
คุณสามารถทดสอบการแยกวิเคราะห์ bash ได้โดยรอดำเนินการล่วงหน้าecho
และออกจาก|
(ไปป์)
echo cat script.sh \| at now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes
echo at -f script.sh now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes
หากต้องการดูงานที่กำหนดเวลาไว้ให้ใช้ atq
และเนื้อหางาน (สภาพแวดล้อม vars การติดตั้งและคำสั่ง / script) at -c [jobid]
ด้วย
ระบบเป็นส่วนหนึ่งของ cron และพรอมต์แบบโต้ตอบจะจับสถานะปัจจุบันทั้งหมดของเชลล์ของคุณดังนั้นคุณจึงสามารถรันคำสั่งได้โดยไม่ต้องระบุพา ธ สัมบูรณ์
ฉันรู้ว่ามันเป็นเธรดที่เก่ากว่า แต่ฉันต้องการเพิ่มสิ่งที่เกี่ยวข้องกับค่าสุ่มที่ฉันใช้บ่อยมาก แทนที่จะใช้ตัวแปร $ RANDOM ที่มีช่วงคงที่และ จำกัด ฉันมักจะสร้างค่าสุ่มช่วงโดยพลการในเชลล์ด้วย
dd if=/dev/urandom bs=4 count=1 2>/dev/null | od -N4 -t u4 -A none
ดังนั้นคุณสามารถทำได้ตัวอย่างเช่น
FULLRANDOM=$(dd if=/dev/urandom bs=4 count=1 2>/dev/null | od -N4 -t u4 -A none)
และเอาชนะข้อ จำกัด บางประการที่กล่าวถึงในหัวข้อนี้
~$info dd
และฉันเข้าใจสิ่งที่เกิดขึ้นทางด้านซ้ายของ|
แต่ไม่สามารถแยกออกทางด้านขวาได้ ดังนั้นสำหรับฉันและคนอื่น ๆ ที่สนใจในovercoming some restrictions
การสร้างมูลค่าแบบสุ่มทำไมไม่ใช้เวลาสักครู่เพื่ออธิบาย RHS และทำการเสนอขายที่แข็งแกร่งขึ้นเพื่อใช้แนวทางของคุณ คำอธิบายเชิงลึกทำให้ผู้คนรู้สึกสบายใจกับกระบวนการที่คุณแนะนำและประโยชน์ที่ได้รับขอบคุณ
สำหรับผู้ที่ googled มาที่นี่:
หากคุณใช้ anacron (เดสก์ท็อปและแล็ปท็อป Ubuntu) คุณสามารถแก้ไขได้
/etc/anacrontab
และเพิ่ม
RANDOM_DELAY=XX
โดยที่ XX คือจำนวนนาทีที่คุณต้องการชะลองานพื้นฐาน
Anacron ก็เหมือนกับ cron แต่ไม่ได้คาดหวังว่าคอมพิวเตอร์ของคุณจะเป็นแบบ 24x7 (เช่นแล็ปท็อปของเรา) และจะเรียกใช้สคริปต์ที่พลาดไปเนื่องจากระบบไม่ทำงาน
คุณสามารถลองใช้ตัวอย่างนี้เพื่อใช้เวลาสุ่มก่อนดำเนินการคำสั่ง:
#!/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"
แล้วการสร้างสคริปต์ที่เขียน crontab ใหม่ทุกวันล่ะ?