Saya membutuhkan kemampuan untuk menjalankan skrip PHP 20 kali sehari pada waktu yang benar-benar acak. Saya juga ingin itu hanya berjalan antara jam 9 pagi - 11 malam.
Saya terbiasa membuat cron job di linux.
Saya membutuhkan kemampuan untuk menjalankan skrip PHP 20 kali sehari pada waktu yang benar-benar acak. Saya juga ingin itu hanya berjalan antara jam 9 pagi - 11 malam.
Saya terbiasa membuat cron job di linux.
Jawaban:
Jika saya mengerti apa yang Anda cari, Anda perlu melakukan sesuatu yang sedikit berantakan, seperti memiliki tugas cron yang menjalankan skrip bash yang mengacak waktu proses ... Sesuatu seperti ini:
crontab:
0 9 * * * /path/to/bashscript
dan di / path / ke / 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
Beberapa catatan: pendekatan ini sedikit boros sumber daya, karena menjalankan 20 proses latar belakang pada jam 9 pagi, yang masing-masing menunggu beberapa menit secara acak (hingga 14 jam, yaitu jam 11 malam), kemudian meluncurkan skrip php dan keluar. Selain itu, karena ini menggunakan jumlah menit acak (bukan detik), waktu mulai tidak seacak mungkin. Tapi $ ACAK hanya naik menjadi 32.767, dan ada 50.400 detik antara jam 9 pagi dan 11 malam, akan sedikit lebih rumit untuk mengacak detik juga. Terakhir, karena waktu mulai acak dan tidak bergantung satu sama lain, mungkin (tetapi tidak sangat mungkin) dua atau lebih contoh skrip akan dimulai secara bersamaan.
((maxdelay = 14 * 60))
Atau ((delay = $RANDOM % maxdelay))
). The sleep
Argumen masih perlu cara Anda memilikinya (meskipun Anda bisa menambahkan spasi, jika diinginkan).
sleep $[ ( $RANDOM % 60 ) + 1 ]s && some_script.sh
Ya, ya, pertanyaannya sudah lebih dari satu tahun, tapi mungkin saya bisa menambahkan sesuatu yang berguna:
Bagaimana cara membuat sesuatu secara acak 20 kali sehari antara jam 9 pagi dan 11 malam? Itu agak rumit dalam cron, karena Anda membagi 14 jam dengan 20 kali eksekusi. Saya tidak terlalu menyukai jawaban lain karena mereka memerlukan penulisan skrip bash wrapper untuk skrip php Anda.
Namun, jika Anda mengizinkan saya untuk mengurangi pembatasan waktu dan frekuensi menjadi 13 kali antara jam 8:30 pagi dan 11:09 malam, ini mungkin berhasil, dan semuanya dalam batasan crontab Anda:
30 8-21/* * * * sleep ${RANDOM:0:2}m ; /path/to/script.php
$ {ACAK: 3: 2} menggunakan $ ACAK bash yang telah disebutkan orang lain di atas, tetapi menambahkan bash array slicing. Karena variabel bash tidak diketik, angka 16-bit bertanda pseudo-random akan dipotong ke 2 pertama dari 5 digit desimalnya, memberi Anda satu baris ringkas untuk menunda cronjob Anda antara 10 dan 99 menit (meskipun distribusinya bias ke arah 10 hingga 32).
Hal berikut mungkin juga berhasil untuk Anda, tetapi menurut saya memang "kurang acak" karena beberapa alasan (mungkin Hukum Benford dipicu oleh pemodulasian bilangan acak semu. Hei, saya tidak tahu, saya gagal dalam matematika ... Salahkan di pesta!):
30 8-21/* * * * sleep $[RANDOM\%90]m ; /path/to/script.php
Anda perlu merender modulus sebagai '\%' di atas karena cron (yah, setidaknya Linux 'vixie-cron') mengakhiri baris ketika menemukan '%' yang tidak dapat dihilangkan.
Mungkin Anda bisa mendapatkan 7 eksekusi skrip yang tersisa di sana dengan menambahkan baris lain dengan rentang 7 jam lainnya. Atau kendurkan batasan Anda untuk berlari antara jam 3 pagi dan 11 malam.
$[(RANDOM/368)+10]
?
$((RANDOM % 90 + 10))
Tes: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
digunakan bash
sebelum Anda menggunakan $RANDOM
. Jika Anda memiliki vixie-cron
(tampaknya kasus saya di Ubuntu), maka Anda dapat menambahkan SHELL=/bin/bash
ke atas. Ada lebih banyak alternatif untuk versi cron lainnya di sini: superuser.com/a/264541/260350
crontab: errors in crontab file, can't install. Do you want to retry the same edit?
bantuan
Jadi saya menggunakan yang berikut ini untuk menjalankan perintah antara 1AM dan 330AM
0 1 * * * perl -le 'sleep rand 9000' && *command goes here*
Itu telah memenuhi kebutuhan acak saya untuk saya. Itu berarti 9.000 detik == 150 menit == 2,5 jam
Cron menawarkan RANDOM_DELAY
variabel. Lihat crontab(5)
detailnya.
Variabel RANDOM_DELAY memungkinkan penundaan permulaan pekerjaan dengan jumlah menit acak dengan batas atas yang ditentukan oleh variabel.
Ini terlihat secara umum dalam anacron
pekerjaan, tetapi juga dapat berguna dalam a crontab
.
Anda mungkin perlu berhati-hati dengan ini jika Anda memiliki beberapa pekerjaan yang berjalan dengan perincian (menit) yang baik dan pekerjaan lain yang kasar.
RANDOM_DELAY
itu dibuat sekali dan tetap konstan untuk seluruh runtime daemon.
RANDOM_DELAY
bendera adalah fitur dari cronie-crond sementara Ubuntu tampaknya berjalan vixie-cron
yang tidak memiliki bendera ini.
Pikiran pertama saya adalah membuat satu pekerjaan cron yang meluncurkan 20 pekerjaan yang dijadwalkan secara acak. The at
utilitas (http://unixhelp.ed.ac.uk/CGI/man-cgi?at) digunakan untuk mengeksekusi perintah pada waktu yang ditentukan.
Saya akhirnya menggunakan sleep $(( 1$(date +%N) % 60 )) ; dostuffs
(kompatibel dengan bash & sh)
Awalan 1 adalah untuk memaksa interpretasi NON basis 8 tanggal +% N (misalnya 00551454)
Jangan lupa untuk keluar% menggunakan \% dalam file crontab
* * * * * nobody sleep $(( 1$(date +\%N) \% 60 )) ; dostuffs
date
(yang mungkin Anda lakukan di sebagian besar Linux, tetapi tidak di Busybox, MacOS standar, atau berbagai platform turunan BSD lainnya).
Solusi al-x tidak bekerja untuk saya karena perintah crontab tidak dijalankan di bash tetapi di sh saya kira. Apa yang berhasil adalah:
30 8 * * * bash -c "sleep $[RANDOM\%90]m" ; /path/to/script.py
$[ ... ]
sudah usang sintaks sejak waaaay kembali; untuk apa pun dari milenium ini, Anda akan lebih memilih $((RANDOM\%90))m
sintaks yang kompatibel dengan POSIX (tetapi tentu saja RANDOM
masih hanya Bash).
at -f [file] [timespec]
atau
echo [command] | at [timespec]
atau
at [timespec]
... dan spesifikasi interaktif seperti script
rekaman.
At menjalankan teks yang disediakan di stdin atau dalam file yang ditentukan oleh -f [file]
.
Berikut [timespec]
tata bahasanya . Bisa jadi seperti ini:
0100
, 2359
,1620
now + 10 minutes
2071-05-31 - 5 hours 12 minutes UTC
Jika Anda secara eksplisit menentukan zona waktu, beberapa versi timespec mungkin hanya memungkinkan UTC
untuk argumen zona waktu opsional.
cat script.sh | at now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes
at -f script.sh now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes
Anda dapat menguji penguraian bash dengan melakukan pra-tunggu echo
dan keluar dari |
(pipa).
echo cat script.sh \| at now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes
echo at -f script.sh now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes
Untuk melihat pekerjaan yang dijadwalkan, gunakan atq
dan isi pekerjaan (lingkungan vars, setup, dan perintah / skrip) dengan at -c [jobid]
.
Sistem adalah bagian dari cron, dan prompt interaktif benar-benar menangkap seluruh status shell Anda saat ini, sehingga Anda dapat menjalankan perintah tanpa menentukan jalur absolut.
Bagi yang googling caranya disini:
Jika Anda menggunakan anacron (desktop dan laptop Ubuntu), Anda dapat mengedit
/etc/anacrontab
dan tambahkan
RANDOM_DELAY=XX
Di mana XX adalah jumlah menit Anda ingin menunda pekerjaan dasar.
Anacron seperti cron tetapi tidak mengharapkan komputer Anda dalam 24x7 (seperti laptop kami) dan akan menjalankan skrip yang terlewat karena sistem sedang down.
Anda dapat mencoba dengan contoh ini untuk menggunakan waktu acak sebelum menjalankan perintah:
#!/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"
Bagaimana dengan membuat skrip yang menulis ulang crontab setiap hari?
Saya menyadari ini adalah utas yang lebih lama, tetapi saya ingin menambahkan satu hal terkait nilai acak yang sering saya gunakan. Alih-alih menggunakan variabel $ RANDOM dengan rentang tetap dan terbatas, saya sering membuat nilai acak rentang acak di shell dengan
dd if=/dev/urandom bs=4 count=1 2>/dev/null | od -N4 -t u4 -A none
jadi Anda bisa melakukannya, misalnya,
FULLRANDOM=$(dd if=/dev/urandom bs=4 count=1 2>/dev/null | od -N4 -t u4 -A none)
dan mengatasi beberapa batasan yang dibahas di utas ini.
~$info dd
dan saya bisa mengerti apa yang terjadi di sisi kiri |
, tetapi tidak bisa melihat sisi kanan. Jadi, bagi saya dan orang lain yang tertarik pada overcoming some restrictions
pembuatan nilai acak, mengapa tidak meluangkan waktu sejenak untuk menjelaskan RHS, dan membuat promosi yang lebih kuat untuk menggunakan pendekatan Anda. Kedalaman penjelasannya membuat orang nyaman dengan proses yang Anda sarankan dan manfaatnya. Terima kasih.