2012-01-28 17 views
61

Potrzebuję możliwość uruchomienia skryptu PHP 20 razy dziennie w zupełnie losowych razy. Chcę też, aby biegał tylko między godziną 9 a 23.Cron zadania i losowe czasy, w określonych godzinach

Jestem zaznajomiony z tworzeniem zadań crona w systemie Linux.

+0

Pytanie nie jest zbyt dobrze postawione. Ostatecznie chcesz rozdać 20 punktów na osi czasu między godziną 9 a 11 rano. Ale czy istnieją ograniczenia dotyczące minimalnej różnicy czasu? Czy nic nie jest do zaakceptowania w godzinach od 9:00 do 10:30? Jedynym sposobem, aby to zrobić, wydaje się być możliwy pomysł Klausa: wybierz 20 razy o 09:00, co pozwoli ci spełnić wszelkie ograniczenia, a następnie zaplanuj rzeczy z "na". –

Odpowiedz

25

Jeśli dobrze rozumiem, co szukasz, musisz zrobić coś trochę brudny, jakby zadanie cron, który uruchamia skrypt bash, który losuje czasy Uruchom ... coś takiego:

crontab:

0 9 * * * /path/to/bashscript 

a/ścieżka/do/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 

kilka uwag: to podejście jest trochę marnotrawstwo zasobów, ponieważ odpala 20 procesów w tle na 9a m, z których każdy czeka na losową liczbę minut (do 14 godzin, tj. 23.00), a następnie uruchamia skrypt php i kończy działanie. Ponadto, ponieważ używa losowej liczby minut (nie sekund), czasy rozpoczęcia nie są tak przypadkowe, jak mogłyby być. Ale $ RANDOM wzrasta do 32 767, a między godziną 9 a 23 jest 50 400 sekund, to trochę bardziej skomplikowane losowanie tych sekund. Wreszcie, ponieważ czasy rozpoczęcia są losowe i niezależne od siebie, możliwe jest (ale mało prawdopodobne), że dwa lub więcej wystąpień skryptu zostanie uruchomionych jednocześnie.

+1

Możesz uczynić arytmetyczne przypisania bardziej czytelnymi, upuszczając znak dolara i przesuwając podwójne pareny w lewo (np. '((Maxdelay = 14 * 60))' lub '((delay = $ RANDOM% maxdelay))'). Argument "uśpienia" nadal musi być taki, jaki masz (chociaż możesz dodać spacje, jeśli chcesz). –

+0

To działało również dla mnie. Mój niestandardowy skrypt bash wygląda poniżej: 'sleep $ [($ RANDOM% 60) + 1] s && some_script.sh' –

5

Moja pierwsza myśl to utworzenie jednego zadania cron uruchamiającego 20 losowo zaplanowanych zadań. Narzędzie at (http://unixhelp.ed.ac.uk/CGI/man-cgi?at) służy do wykonywania poleceń w określonym czasie.

+0

Przykład użycia at jest tutaj: http://stackoverflow.com/a/6136145/803174 – Kangur

88

Tak, tak, chodzi o to ponad rok, ale może uda mi się dodać coś pożytecznego:

Jak cron coś w losowym przesunięciem 20 razy dziennie pomiędzy 9am i 11pm? To trochę trudne w cronie, ponieważ dzielisz 14 godzin przez 20 czasów wykonania. Nie podobają mi się inne odpowiedzi, ponieważ wymagają napisania skryptu otoki bash dla skryptu php.

Jednakże, jeśli będziesz pozwalają mi wolność, aby złagodzić częstotliwości taktowania i ograniczenie do 13 razy między 8:30 a 11:09 po południu, to może załatwić sprawę, a wszystko w ramach crontab:

30 8-21/* * * * sleep ${RANDOM:0:2}m ; /path/to/script.php 

$ {RANDOM: 3: 2} wykorzystuje $ RANDOM basha, o którym wspomnieli inni, ale dodaje cięcie tablicy bash. Ponieważ zmienne bash są nieopisane, pseudolosowy podpisany 16-bitowy numer zostaje obcięty do pierwszych 2 z 5 cyfr dziesiętnych, dając ci zwięzły wykładnik liniowy opóźniający cronjob od 10 do 99 minut (chociaż rozkład jest skierowany w stronę 10 do 32).

Następujące mogą również działać dla ciebie, ale okazało się, że z jakiegoś powodu są "mniej losowe" (być może prawo Benforda jest wyzwalane przez modulowanie liczb pseudolosowych .. Hej, nie wiem, policzyłem matematykę. .. Winić go na bash):

30 8-21/* * * * sleep $[RANDOM\%90]m ; /path/to/script.php 

trzeba uczynić moduł jako „\%” powyżej, ponieważ cron (no, przynajmniej Linuksowy vixie-cron ') kończy wiersz po napotkaniu Niecytowany' % ".

Może uda ci się zdobyć 7 pozostałych skryptów, dodając kolejną linię z innym 7-godzinnym zakresem. Możesz też złagodzić swoje ograniczenia, aby biegać między godziną 3 a 23.

+4

Podoba mi się późna odpowiedź. Ale jeśli próbujesz wygenerować losową liczbę całkowitą równomiernie rozłożoną w przedziale od 10 do 99, a wynik RANDOM wynosi od 0 do 32 767, dlaczego nie zrobiłbyś po prostu '$ [(RANDOM/368) +10] ? – jsdalton

+1

@jsdalton: Czy operator modulo nie byłby lepszy? '$ ((RANDOM% 90 + 10))' Test: 'dla i w {0..9999}; do echo $ ((RANDOM% 90 + 10)); zrobione | sortuj uniq -c' – geon

+1

W wielu systemach cron nie używa domyślnie bash, więc lepiej byłoby uniknąć bashizmu '$ RANDOM':' sleep $ (($ (od -N1 -tuC -An/dev/urandom) \% 90)) m. – pabouk

37

Więc używam następujące uruchomić polecenie między 1 w nocy i 330AM

0 1 * * * perl -le 'sleep rand 9000' && *command goes here* 

To zostało dbanie o moich potrzebach losowych dla mnie. To 9000 sekund == == 150 minut 2,5 godziny

3

skończyło się stosując sleep $((1$(date +%N) % 60)) ; dostuffs (zgodny atakujących & sh)

W 1 przedrostek jest wymuszenie nie zachodzi 8 interpretacji terminu +% N (np 00551454)

nie zapomnij uciec% \% w użyciu takiego pliku

* * * * * nobody sleep $((1$(date +\%N) \% 60)) ; dostuffs

+2

Jeśli ktoś się zastanawia, tak jak ja:% N zawiera aktualne nanopy, ale niektóre strony podręcznika man nie zawierają informacji na ten temat. Jest to bardzo sprytne rozwiązanie dla osób, które po prostu potrzebują "pewnej losowości" łatwo na polecenie. –

10

Cron oferuje zmienną RANDOM_DELAY. Szczegółowe informacje można znaleźć na stronie crontab(5).

Zmienna RANDOM_DELAY umożliwia opóźnienie firmach pracy przez losową ilości minut przy górnej granicy określonej przez zmienną.

Jest to powszechnie widziane w zadaniach anacron, ale może też być przydatne w przypadku crontab.

Być może trzeba zachować ostrożność, jeśli masz kilka zadań, które działają przy dobrej szczegółowości (minuta) i innych, które są gruboziarniste.

+0

Chciałbym użyć zmiennej RANDOM_DELAY, ale nie mogę znaleźć żadnej wskazówki w podręczniku crontab (5) na Ubuntu 14.04.4 LTS. – Exocom

+0

To niefortunne. Zastanawiam się, czy nie jest tam obsługiwany. Widzę to udokumentowane w tej stronie na Centos 7 i Arch Linux. –

+2

to wydaje się być poprawną odpowiedzią, ale czy możesz podać przykład? – chovy

0

at -f [file] [timespec]

lub

echo [command] | at [timespec]

lub

at [timespec] ... i interaktywne specyfikacja jak nagrania script „s.

poleceń

Na biegnie tekst dostarczyć na stdin lub w pliku określonym przez -f [file].

timespec

Oto [timespec] grammar. Może to być coś takiego:

  • 24-godzinny czas jako 4-cyfrowy int, np. 0100, 2359, 1620
  • now + 10 minutes
  • 2071-05-31 - 5 hours 12 minutes UTC

Jeśli wyraźnie określające strefę czasową, some versions z timespec może umożliwić tylko UTC dla opcjonalnego argumentu stref czasowych.

Przykład

cat script.sh | at now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes

at -f script.sh now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes

Wypróbuj ...

można przetestować analizowania bash przez wstawienie echo i ucieczki | (rury).

echo cat script.sh \| at now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes

echo at -f script.sh now + $(($RANDOM % 10)) hours $(($RANDOM % 60)) minutes

Aby zobaczyć zaplanowane zadania, należy atq i pracy zawartość (środowisko Vars, setup, a komenda/script) z at -c [jobid].

Uwaga

System jest częścią cron i interaktywny wiersz faktycznie rejestruje cały aktualny stan swojej skorupy, dzięki czemu można wykonywać polecenia bez określenia ścieżki bezwzględnej.

0

Dla tych, którzy google aż tutaj:

Jeśli używasz anacron (pulpit Ubuntu i laptopa), a następnie można edytować

/etc/anacrontab 

i dodać

RANDOM_DELAY=XX 

gdzie XX jest ilość minut, które chcesz opóźnić zadanie podstawowe.

Anacron jest jak cron, ale nie spodziewa się, że komputer będzie na 24x7 (podobnie jak nasze laptopy) i uruchomi skrypty, które stracił, ponieważ system nie działa.

Powiązane problemy