2012-01-28 18 views
61

Ho bisogno della possibilità di eseguire uno script PHP 20 volte al giorno in momenti completamente casuali. Voglio anche che funzioni solo tra le 9:00 e le 23:00.Cron jobs e orari casuali, entro determinati orari

Ho familiarità con la creazione di processi cron in linux.

+0

La domanda non è molto ben presentata. In definitiva, si desidera distribuire 20 punti sull'asse del tempo tra le 9:00 e le 11:00. Ma ci sono vincoli sulla differenza temporale minima? Non è accettabile nulla tra le 9 e le 10:30? L'unico modo per farlo in modo accettabile sembra l'idea di Klaus: seleziona le tue 20 volte alle 09:00, che ti permettono di soddisfare qualsiasi vincolo che potresti avere, quindi pianifica le cose con "at". –

risposta

25

Se ho capito quello che stai cercando, avrete bisogno di fare qualcosa di un po 'confuso, come avere un job cron che esegue uno script bash che casualmente i tempi di esecuzione ... Qualcosa di simile:

crontab:

0 9 * * * /path/to/bashscript 

e/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 

alcune note: questo approccio un po 'uno spreco di risorse, come si spara 20 processi in background in 9a m, ognuno dei quali attende un numero casuale di minuti (fino a 14 ore, ovvero 11pm), quindi avvia lo script php ed esce. Inoltre, poiché utilizza un numero casuale di minuti (non secondi), i tempi di inizio non sono così casuali come potrebbero essere. Ma $ RANDOM sale a 32.767, e ci sono 50.400 secondi tra le 9 e le 23, sarebbe anche un po 'più complicato randomizzare anche i secondi. Infine, poiché i tempi di inizio sono casuali e indipendenti l'uno dall'altro, è possibile (ma non molto probabile) che due o più istanze dello script vengano avviate contemporaneamente.

+1

È possibile rendere più leggibili le assegnazioni aritmetiche eliminando il simbolo del dollaro e spostando il doppio paren a sinistra (ad esempio '((maxdelay = 14 * 60))' o '((ritardo = $ RANDOM% maxdelay))'). L'argomento 'sonno' deve ancora essere il modo in cui lo hai (anche se potresti aggiungere degli spazi, se lo desideri). –

+0

Questo ha funzionato anche per me. Il mio script bash personalizzato appare come sotto 'sleep $ [($ RANDOM% 60) + 1] s && some_script.sh' –

5

Il mio primo pensiero sarebbe quello di creare un job cron che lanci 20 programmati a caso sui job. L'utilità at (http://unixhelp.ed.ac.uk/CGI/man-cgi?at) viene utilizzata per l'esecuzione di comandi all'ora specificata.

+0

Un esempio di utilizzo è qui: http://stackoverflow.com/a/6136145/803174 – Kangur

88

Sì, sì, la questione è più di un anno, ma forse posso aggiungere qualcosa di utile:

Come cron qualcosa in un caso offset di 20 volte al giorno 9:00-23:00? È piuttosto complicato in cron, perché stai dividendo 14 ore per 20 tempi di esecuzione. Le altre risposte non mi piacciono molto perché richiedono la scrittura di uno script di wrapper bash per il tuo script php.

Tuttavia, se mi permettete la libertà di facilitare i tempi e la frequenza di restrizione a 13 volte tra le 8:30 e le 23:09, questo potrebbe fare il trucco, e tutto entro i confini del vostro crontab:

$ {RANDOM: 3: 2} utilizza bash's $ RANDOM che altre persone hanno menzionato sopra, ma aggiunge il bash array slicing. Poiché le variabili di bash non sono tipizzate, il numero a 16 bit con segno pseudo-casuale viene troncato alle prime 2 delle 5 cifre decimali, fornendo una breve corrispondenza per ritardare il cronjob tra 10 e 99 minuti (sebbene la distribuzione sia distorta verso 10 a 32).

Il seguente potrebbe funzionare anche per te, ma ho trovato che è "meno casuale" per qualche ragione (forse la legge di Benford è innescata modulando numeri pseudo-casuali.Ehi, non lo so, ho bocciato la matematica. .. Date la colpa a bash):!

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

è necessario per rendere il modulo come '\%' sopra, perché cron (beh, almeno Linux 'vixie-cron') termina la linea quando incontra un escape ' %'.

Forse potresti ottenere le restanti 7 esecuzioni di script lì aggiungendo un'altra riga con un altro intervallo di 7 ore. Oppure rilassa la tua limitazione per correre tra le 3:00 e le 23:00.

+4

Mi piace la risposta tardiva. Ma se stai cercando di generare un intero casuale distribuito uniformemente nell'intervallo da 10 a 99 e l'output di RANDOM è compreso tra 0 e 32.767, perché non dovresti semplicemente fare '$ [(RANDOM/368) +10]' ? – jsdalton

+1

@jsdalton: l'operatore modulo non sarebbe migliore? '$ ((RANDOM% 90 + 10))' Test: 'per i in {0..9999}; do echo $ ((RANDOM% 90 + 10)); fatto | ordinare | uniq -c' – geon

+1

Su molti sistemi cron non usa bash di default quindi potrebbe essere meglio evitare il bashismo '$ RANDOM':' sleep $ (($ (od -N1 -tuC -An/dev/urandom) \% 90)) m'. – pabouk

37

Così sto utilizzando la seguente per eseguire un comando tra le 01:00 e 330am

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

Questo è stato preso cura dei miei bisogni casuali per me. Questo è 9000 secondi == 150 minuti == 2,5 ore

3

ho finito per usare sleep $((1$(date +%N) % 60)) ; dostuffs (bash compatibile & sh)

Il 1 prefisso è quello di forzare base di NON 8 interpretazione data +% N (ad esempio 00.551.454)

non dimenticare di fuggire% utilizzando \% in un file crontab

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

+2

Se qualcuno si chiede, come me:% N fornisce gli attuali nanos, ma alcune pagine man mancano di informazioni per questo. Questa è una soluzione molto intelligente per le persone che hanno solo bisogno di "un po 'di casualità" facilmente per comando. –

10

Cron offre una variabile RANDOM_DELAY. Vedi crontab(5) per i dettagli.

La variabile RANDOM_DELAY permette ritardare startup lavoro da quantità casuale di minuti con limite superiore specificato dalla variabile.

questo è visto comunemente nei anacron posti di lavoro, ma può anche essere utile in un crontab.

Potrebbe essere necessario fare attenzione con questo se si dispone di alcuni lavori che funzionano a granularità fine (minuto) e altri che sono di massima.

+0

Mi piacerebbe utilizzare la variabile RANDOM_DELAY, ma non riesco a trovare alcun suggerimento nella manpage di crontab (5) su Ubuntu 14.04.4 LTS. – Exocom

+0

Questo è un peccato. Mi chiedo se non è supportato lì. Lo vedo documentato in quella manpage su Centos 7 e Arch Linux. –

+2

questa sembra la risposta corretta ma puoi fare un esempio? – chovy

0

at -f [file] [timespec]

o

echo [command] | at [timespec]

o

at [timespec] ... e interattivo specifiche come la registrazione script s'.

Comando

Al corre il testo forniscono su stdin o nel file specificato da -f [file].

timespec

Ecco il [timespec] grammar. Può essere qualcosa del tipo:

  • 24 ore come int a 4 cifre, ad es. 0100, 2359, 1620
  • now + 10 minutes
  • 2071-05-31 - 5 hours 12 minutes UTC

Se stai specificare esplicitamente il fuso orario, some versions della timespec potrebbe consentire solo UTC per l'argomento fuso orario opzionale.

Esempio

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

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

Provalo ...

è possibile testare il parsing bash pre-attesa echo e sfuggire al | (tubo).

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

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

Per vedere i lavori programmati, utilizzare atq e di lavoro contenuti (ambiente VAR, messa a punto, e il comando/script) con at -c [jobid].

Nota

Il sistema fa parte di cron, ed il prompt interattivo in realtà coglie tutto lo stato attuale della vostra shell, in modo da poter eseguire i comandi senza specificare percorsi assoluti.

0

Per coloro che googled il modo in qui:

Se si sta utilizzando anacron (desktop Ubuntu e laptop) quindi è possibile modificare

/etc/anacrontab 

e aggiungere

RANDOM_DELAY=XX 

Dove XX è il numero di minuti che si desidera ritardare il lavoro di base.

Anacron è come cron ma non si aspetta che il tuo computer sia su 24x7 (come i nostri laptop) e eseguirà gli script che ha mancato perché il sistema era inattivo.