È possibile eseguire un cronjob ogni tre giorni? O forse 10 volte al mese.
È possibile eseguire un cronjob ogni tre giorni? O forse 10 volte al mese.
Risposte:
Eseguilo ogni tre giorni ...
0 0 */3 * *
Che ne dici di quello?
Se vuoi che venga eseguito in giorni specifici del mese, come il 1 °, 4 °, 7 °, ecc ... allora puoi semplicemente avere un condizionale nel tuo script che controlla il giorno corrente del mese.
if (((date('j') - 1) % 3))
exit();
oppure, come sottolinea @mario, puoi usare date ('k') per ottenere il giorno dell'anno invece di farlo in base al giorno del mese.
0 0 */3 * *
significa eseguire il 1 °, 4 °, 7 °, ecc. ( */3
significa 1-31/3
significa 1,4,7...31
) quindi il divario sarà minore alla fine del mese. (Verrà eseguito 2 giorni consecutivi se il mese precedente aveva 31 giorni.) date('j') % 3
Ha un problema simile in quanto il modello si riavvia ogni anno e gli anni non hanno un numero di giorni divisibile per 3.
* * */3 * * that says, every minute of every hour on every three days.
0 0 */3 * * says at 00:00 (midnight) every three days.
Non sono uno specialista di cron, ma che ne dici di:
0 */72 * * *
Verrà eseguito ogni 72 ore senza interruzioni.
then at 2019-02-28 00:00:00 then at 2019-03-01 00:00:00
Poiché cron è "senza stato", non può esprimere con precisione "frequenze", ma solo "schemi" che (apparentemente) confronta continuamente con l'ora corrente.
Riformulare la tua domanda lo rende più ovvio: "è possibile eseguire un cronjob alle 00:01 ogni notte tranne saltare le notti quando è stato eseguito entro 2 notti?" Quando cron confronta l'ora corrente con gli schemi temporali delle richieste di lavoro, non è possibile che cron sappia se ha eseguito il tuo lavoro in passato.
Di solito devi terminare quell'evento ricorrente e riavviarne uno completamente nuovo; questo illustra l'espressività limitata di come anche le app di calendario complicate rappresentino schemi ripetitivi. E, naturalmente, i calendari hanno molto stato: ogni singolo evento può essere eliminato o riprogrammato in modo indipendente [nella maggior parte delle app di calendario]).
Inoltre, probabilmente vorrai fare il tuo lavoro ogni 3 notti in caso di successo , ma se l'ultima non è riuscita, riprovare immediatamente, forse la notte successiva (non aspettare altri 3 giorni) o anche prima, come un'ora dopo (ma smetti di riprovare all'arrivo del mattino). Chiaramente, cron non può sapere se il tuo lavoro è andato a buon fine e il pattern non può anche esprimere un programma alternativo di "ripetizione" più frequente.
COMUNQUE-- Puoi fare quello che vuoi da solo. Scrivi uno script, dì a cron di eseguirlo di notte alle 00:01. Questo script potrebbe controllare il timestamp di qualcosa * che registra l '"ultima esecuzione" e, se è stato> 3 giorni fa **, eseguire il lavoro e reimpostare il timestamp dell' "ultima esecuzione".
(* quell'indicatore timestamp è un po 'di stato persistente che puoi manipolare ed esaminare, ma che cron non può)
** fai attenzione all'aritmetica del tempo se utilizzi l'ora leggibile dall'uomo: due volte l'anno, alcuni giorni hanno 23 o 25 ore nel loro giorno e 02: 00-02: 59 si verifica due volte in un giorno o no alle tutti. Usa UTC per evitarlo.
0 0 1-30/3 * *
Questo verrà eseguito ogni tre giorni a partire dal primo. Ecco le 20 corse programmate:
Non penso che tu abbia ciò di cui hai bisogno con:
0 0 */3 * * ## <<< WARNING!!! CAUSES UNEVEN INTERVALS AT END OF MONTH!!
Sfortunatamente, * / 3 imposta l'intervallo ogni n giorni del mese e non ogni n giorni . Vedi: spiegazione qui . Alla fine del mese è garantita un'emissione ricorrente.
1st at 2019-02-01 00:00:00
then at 2019-02-04 00:00:00 << 3 days, etc. OK
then at 2019-02-07 00:00:00
...
then at 2019-02-25 00:00:00
then at 2019-01-28 00:00:00
then at 2019-03-01 00:00:00 << 1 day WRONG
then at 2019-03-04 00:00:00
...
Secondo questo articolo , è necessario aggiungere un po 'di matematica modulo al comando in esecuzione per ottenere un VERO "ogni N giorni". Per esempio:
0 0 * * * bash -c '(( $(date +\%s) / 86400 \% 3 == 0 )) && runmyjob.sh
In questo esempio, il lavoro verrà controllato quotidianamente alle 12:00, ma verrà eseguito solo quando il numero di giorni dall'01-01-1970 modulo 3 è 0.
Se vuoi che sia ogni 3 giorni da una data specifica, utilizza il seguente formato:
0 0 * * * bash -c '(( $(date +\%s -d "2019-01-01") / 86400 \% 3 == 0 )) && runmyjob.sh
Che ne dite di:
00 00 * * * every 3 days && echo test
Dov'è every
uno script:
#!/bin/sh
case $2 in
days)
expr `date +%j` % $1 = 0 > /dev/null
;;
weeks)
expr `date +%V` % $1 = 0 > /dev/null
;;
months)
expr `date +%m` % $1 = 0 > /dev/null
;;
esac
Quindi funziona tutti i giorni.
Usare le */3
corse il 3, 6, ... 27, 30 del mese, ma poi è sbagliato dopo che un mese ha un 31 ° giorno. La every
sceneggiatura è sbagliata solo dopo la fine dell'anno.
Dovresti imparare le basi di crontab
.
Modifica il cron tramite comando crontab -e
e poi ⌃ (CTRL)+ Xpoi Ye infine premi ENTER (return)su Mac per salvare il file. Puoi controllare che i nuovi crons siano stati installati da not bycrontab -l
Un file crontab ha cinque campi per specificare i minuti, le ore, il giorno del mese, il mese e il giorno della settimana seguiti dal comando da eseguire a quell'intervallo.
* * * * * command to be executed
- - - - -
| | | | |
| | | | +----- day of week (0-6) (Sunday=0)
| | | +------- month (1-12)
| | +--------- day of month (1-31)
| +----------- hour (0-23)
+------------- min (0-59)
*
nel campo del valore sopra significa tutti i valori legali come tra parentesi graffe per quella colonna.
Qui, ho scritto un post dettagliato a riguardo: Setup Cron in Unix
Se vuoi che venga eseguito in giorni specifici del mese, come il 1 °, 4 °, 7 °, ecc ... allora puoi semplicemente avere un condizionale nel tuo script che controlla il giorno corrente del mese.
Pensavo che tutto ciò di cui avevi bisogno fosse invece di * / 3 che significa ogni tre giorni, usa 1/3 che significa ogni tre giorni a partire dal 1 ° del mese. quindi 7/3 significherebbe ogni tre giorni a partire dal 7 del mese, ecc.
0 0 * * * [ $(($((
data +% - j- 1)) % 3)) == 0 ] && script
Ottieni il giorno dell'anno da date
, offset di 1 per iniziare da 0, controlla se è modulo tre.
( 365-1 ) % 3 == 1
ma ( 1 - 1 ) % 3 == 0
? Penso che il calcolo migliore sarebbe basato sul numero di giorni trascorsi dall'epoca di Unix.