Tamamen rastgele zamanlarda bir PHP betiğini günde 20 kez çalıştırma yeteneğine ihtiyacım var. Ayrıca sadece 09:00 - 23:00 arasında çalışmasını istiyorum.
Linux'ta cron işleri oluşturmaya aşinayım.
Tamamen rastgele zamanlarda bir PHP betiğini günde 20 kez çalıştırma yeteneğine ihtiyacım var. Ayrıca sadece 09:00 - 23:00 arasında çalışmasını istiyorum.
Linux'ta cron işleri oluşturmaya aşinayım.
Yanıtlar:
Ne aradığınızı anlarsam, çalışma sürelerini rastgele hale getiren bir bash betiği çalıştıran bir cron işi gibi biraz dağınık bir şey yapmanız gerekecek ... Bunun gibi bir şey:
crontab:
0 9 * * * /path/to/bashscript
ve / bashscript'e / yolunda:
#!/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
Birkaç not: bu yaklaşım, her biri rastgele birkaç dakika (14 saate kadar, yani 23: 00'a kadar) boyunca bekleyen (14 saate kadar, yani 11: 00'a kadar) saat 9'da 20 arka plan işlemini başlattığı için biraz kaynak israfına neden olur ve ardından php betiğini başlatır ve çıkışlar. Ayrıca, rastgele bir dakika sayısı (saniye değil) kullandığı için, başlangıç zamanları olabildiğince rastgele değildir. Ancak $ RANDOM yalnızca 32.767'ye kadar çıkıyor ve sabah 9 ile akşam 11 arasında 50.400 saniye var, saniyeleri rastgele hale getirmek de biraz daha karmaşık olurdu. Son olarak, başlangıç zamanları rastgele ve birbirinden bağımsız olduğundan, komut dosyasının iki veya daha fazla örneğinin aynı anda başlatılması mümkündür (ancak pek olası değildir).
((maxdelay = 14 * 60))veya ((delay = $RANDOM % maxdelay))) aritmetik atamaları daha okunaklı hale getirebilirsiniz . sleepArgümanı hala (istenirse Eğer boşluk ekleyebilirsiniz rağmen) sende yolu olması gerekiyor.
sleep $[ ( $RANDOM % 60 ) + 1 ]s && some_script.sh
Evet, evet, soru bir yıldan eski, ama belki işe yarar bir şeyler ekleyebilirim:
Bir şeyi günde 20 kez sabah 9 ile akşam 11 arasında rastgele bir farkla nasıl kaydedebilirim? Bu cron içinde biraz zor çünkü 14 saati 20 yürütme süresine bölüyorsunuz. Diğer cevapları pek sevmiyorum çünkü php betiğiniz için bir bash sarmalayıcı komut dosyası yazmayı gerektiriyorlar.
Bununla birlikte, zamanlama ve frekans kısıtlamasını 8:30 am ve 23:09 pm arasında 13 kez azaltma özgürlüğüne izin verirseniz, bu hile yapabilir ve hepsi crontab'inizin sınırları dahilinde:
30 8-21/* * * * sleep ${RANDOM:0:2}m ; /path/to/script.php
$ {RANDOM: 3: 2} bash'ın yukarıda bahsettiği $ RANDOM'unu kullanır, ancak bash dizi dilimlemeyi ekler. Bash değişkenleri tiplenmemiş olduğundan, sözde rastgele işaretli 16 bitlik sayı, 5 ondalık basamağının ilk 2'sine kesilerek, cronjob'unuzu 10 ila 99 dakika arasında geciktirmek için size kısa ve öz bir tek satırlık verir (ancak dağıtım, 10 ila 32).
Aşağıdakiler de sizin için işe yarayabilir, ancak bazı nedenlerden dolayı "daha az rastlantısal" olduğunu buldum (belki de Benford Yasası sözde rastgele sayıların modüle edilmesiyle tetikleniyor. Hey, bilmiyorum, matematiği boşverdim ... Suçla bash üzerinde!):
30 8-21/* * * * sleep $[RANDOM\%90]m ; /path/to/script.php
Modülüsünü yukarıdaki '\%' olarak göstermeniz gerekir çünkü cron (en azından Linux 'vixie-cron'), çıkış karaktersiz bir '%' ile karşılaştığında satırı sonlandırır.
Belki kalan 7 komut dosyası yürütmesini başka bir 7 saatlik aralıkla başka bir satır ekleyerek elde edebilirsiniz. Ya da 03:00 ile 23:00 arasında koşmak için kısıtlamanızı gevşetin.
$[(RANDOM/368)+10]?
$((RANDOM % 90 + 10))Test:for i in {0..9999}; do echo $((RANDOM % 90 + 10)); done | sort | uniq -c
$RANDOM: sleep $(( $(od -N1 -tuC -An /dev/urandom) \% 90 ))m.
crontabKullanmadan bashönce kullandığınızdan emin olun $RANDOM. Varsa vixie-cron(Ubuntu'da benim durumum gibi görünüyor), o zaman SHELL=/bin/bashen üste ekleyebilirsiniz . Diğer cron sürümleri için burada daha fazla alternatif var: superuser.com/a/264541/260350
crontab: errors in crontab file, can't install. Do you want to retry the same edit?lütfen yardım alıyorum
Bu yüzden 1AM ile 330AM arasında bir komut çalıştırmak için aşağıdakileri kullanıyorum
0 1 * * * perl -le 'sleep rand 9000' && *command goes here*
Bu benim için rastgele ihtiyaçlarımı karşılıyor. Bu 9000 saniye == 150 dakika == 2,5 saat
Cron bir RANDOM_DELAYdeğişken sunar . Ayrıntılar crontab(5)için bakın.
RANDOM_DELAY değişkeni, iş başlangıcını, değişken tarafından belirlenen üst sınırla rastgele dakika miktarıyla geciktirmeye izin verir.
Bu, anacronişlerde yaygın olarak görülür , ancak aynı zamanda bir crontab.
İnce (dakika) ayrıntı düzeyinde çalışan bazı işleriniz ve kaba işleriniz varsa, buna dikkat etmeniz gerekebilir.
RANDOM_DELAYbir kez kurulduğunu ve arka plan programının tüm çalışma süresi boyunca sabit kaldığını unutmayın .
RANDOM_DELAYBayrak ait özelliğidir Cronie-Crond Ubuntu çalışıyor gibi görünüyor iken vixie-cronbu bayrağı yoksun olan.
İlk düşüncem, 20 iş için rastgele planlanmış bir cron işi oluşturmaktı. Yardımcı atprogram (http://unixhelp.ed.ac.uk/CGI/man-cgi?at) komutları belirtilen zamanda çalıştırmak için kullanılır.
Kullanmaya son verdim sleep $(( 1$(date +%N) % 60 )) ; dostuffs(bash & sh ile uyumlu)
1 önek, tarih +% N'nin 8 tabanlı OLMAYAN yorumlamasını zorlamaktır (ör. 00551454)
Bir crontab dosyasında \% kullanarak% 'dan çıkmayı unutmayın
* * * * * nobody sleep $(( 1$(date +\%N) \% 60 )) ; dostuffs
dateGNU'ya sahipseniz işe yarar (muhtemelen çoğu Linux'ta yaptığınız, ancak Busybox, standart MacOS veya diğer çeşitli BSD'den türetilmiş platformlarda değil).
al-x'in Çözümü benim için çalışmıyor çünkü crontab komutları bash'de değil, sanırım sh'de çalıştırılıyor. Ne anlama geliyor:
30 8 * * * bash -c "sleep $[RANDOM\%90]m" ; /path/to/script.py
$[ ... ]waaaay geri geldiğinden beri kullanımdan kaldırılmış sözdizimi; bu milenyumdan kalan herhangi bir şey için, $((RANDOM\%90))mhangisinin POSIX uyumlu sözdizimi olduğunu tercih edersiniz (ama elbette RANDOMhala yalnızca Bash'dir).
at -f [file] [timespec]
veya
echo [command] | at [timespec]
veya
at [timespec]... ve scriptkaydı gibi etkileşimli özellikler .
Çalıştırıldığında metin stdin'de veya ile belirtilen dosyada sağlanır -f [file].
İşte [timespec]
gramer . Şunun gibi bir şey olabilir:
0100, 2359,1620now + 10 minutes2071-05-31 - 5 hours 12 minutes UTCSaat dilimini açıkça belirtiyorsanız, zaman belirtiminin bazı sürümleri yalnızca UTCisteğe bağlı saat dilimi bağımsız değişkenine izin verebilir .
cat script.sh | at now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes
at -f script.sh now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes
(Boru) ' echoyu önceden bekleyerek ve kaçarak bash ayrıştırmasını test edebilirsiniz |.
echo cat script.sh \| at now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes
echo at -f script.sh now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes
Planlanan işleri görmek için, atqiş içeriğini (ortam değişkenleri, kurulum ve komut / komut dosyası) ile kullanın at -c [jobid].
Sistem cron'un bir parçasıdır ve etkileşimli komut istemi aslında kabuğunuzun tüm mevcut durumunu yakalar, böylece komutları mutlak yollar belirlemeden çalıştırabilirsiniz.
Bunun daha eski bir iş parçacığı olduğunun farkındayım, ancak çok kullandığım rastgele değerle ilgili bir şey eklemek istiyorum. $ RANDOM değişkenini sabit ve sınırlı bir aralıkla kullanmak yerine, genellikle kabukta rastgele aralıklı rasgele değerler yaparım.
dd if=/dev/urandom bs=4 count=1 2>/dev/null | od -N4 -t u4 -A none
örneğin şunları yapabilirsiniz:
FULLRANDOM=$(dd if=/dev/urandom bs=4 count=1 2>/dev/null | od -N4 -t u4 -A none)
ve bu ileti dizisinde tartışılan bazı kısıtlamaların üstesinden gelin.
~$info ddve sol tarafında neler olduğunu anlayabiliyorum |, ancak sağ tarafı ayırt edemiyorum. Öyleyse, ben ve overcoming some restrictionsrastgele değer üretmeyle ilgilenen diğerleri için , neden biraz zaman ayırıp RHS'yi açıklamayalım ve yaklaşımınızı kullanmak için daha güçlü bir adım atmayasınız? Açıklamanın derinliği hem önerdiğiniz süreç konusunda insanları rahatlatır hem de faydaları Teşekkürler.
Burada yolu araştıranlar için:
Anacron kullanıyorsanız (Ubuntu masaüstü ve dizüstü bilgisayar), o zaman düzenleyebilirsiniz
/etc/anacrontab
ve Ekle
RANDOM_DELAY=XX
XX, temel işi ertelemek istediğiniz dakika miktarıdır.
Anacron cron gibidir, ancak bilgisayarınızın 7x24 açık olmasını beklemiyor (dizüstü bilgisayarlarımız gibi) ve sistem çöktüğü için kaçırdığı komut dosyalarını çalıştıracak.
Bu örnekle komutu çalıştırmadan önce rastgele zamanlar kullanmayı deneyebilirsiniz:
#!/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"
Her gün crontab'ı yeniden yazan bir betik oluşturmaya ne dersiniz?