Spiegatore di espressioni cron

Spiega qualsiasi espressione cron — Vixie, Quartz, EventBridge o Jenkins —, elenca le prossime esecuzioni in qualsiasi fuso e segnala le trappole.

Input

Letta come Vixie cron.

Che cosa significa

Alle 00:00 il giorno 13 del mese oppure di venerdì

Campo per campo

CampoScrittoCorrisponde a
Minuto00
Ora00
Giorno del mese1313
Mese*qualsiasi valore
Giorno della settimana5venerdì

A che cosa fare attenzione

  • Entrambi i campi di giorno sono vincolati, quindi cron esegue questo quando ne combacia uno qualsiasi: il giorno del mese o il giorno della settimana, non entrambi insieme. Per questo 13 con venerdì significa il 13 del mese e ogni venerdì, non venerdì 13.

Prossime esecuzioni

    Che cosa fa questo strumento

    Ti rilegge un’espressione cron a parole, elenca le prossime volte in cui scatterà davvero nel fuso orario in cui gira il job, e nomina le cose che l’espressione implica ma non dice. Quest’ultima parte è il punto: un’espressione cron non è mai sbagliata in un modo che produca un errore. Gira nei giorni sbagliati, in silenzio, finché qualcuno non se ne accorge.

    Vengono compresi quattro dialetti anziché uno. La forma a cinque campi che accetta crontab, Quartz con il suo campo dei secondi e le sue regole di calendario, AWS EventBridge con un anno in fondo, e Jenkins con il suo hash. Incollarne uno in uno strumento che ne conosce solo un altro è il modo in cui la maggior parte delle persone scopre che ne esiste più di uno.

    I campi, e quanti sono

    L’espressione classica ha cinque campi separati da spazi, in un ordine fisso: minuto, ora, giorno del mese, mese, giorno della settimana. Ognuno è un asterisco che significa «ogni», un numero, un elenco separato da virgole, un intervallo con un trattino o un passo con una barra. Mesi e giorni si possono scrivere con nomi di tre lettere, quasi sempre più chiari delle cifre.

    • Un asterisco significa qualsiasi valore che il campo può assumere.
    • Un intervallo come 9-17 significa tutti i valori da 9 a 17 inclusi.
    • Un passo come */15 significa ogni 15° valore a partire dal fondo del campo; 9-17/2 avanza dentro un intervallo e 5/15 avanza da 5 fino in cima.
    • Un elenco come 0,30 significa esattamente quei valori.
    • Un intervallo degenere come 13-13 è semplicemente 13: alcune librerie sbagliano qui e lo trattano come un asterisco.

    Un sesto campo è il punto in cui i dialetti si separano. Quartz lo mette davanti e lo legge come secondi; EventBridge lo mette in fondo e lo legge come anno. Sei campi nudi sono quindi davvero ambigui, e questo strumento dice come li ha letti invece di scegliere in silenzio. Racchiudere l’espressione in cron(...) — la sintassi propria di EventBridge — risolve la questione.

    Le macro sono abbreviazioni: @hourly, @daily, @midnight, @weekly, @monthly, @yearly e @annually. Si espandono in espressioni ordinarie, che lo strumento mostra. @reboot è l’eccezione e non è affatto una pianificazione.

    I due campi di giorno, e l’«o» che sembra una «e»

    Una data si può scegliere in due modi diversi — per giorno del mese e per giorno della settimana — e cron ha entrambi i campi. Quando sono entrambi vincolati, il job gira quando combacia uno qualsiasi dei due. Non entrambi.

    Quindi 0 0 13 * 5 non è venerdì 13. È il 13 di ogni mese, e ogni venerdì: circa 64 giorni l’anno invece di uno o due. L’espressione sembra una congiunzione e si comporta come una disgiunzione, nulla segnala un errore, e il job semplicemente gira più spesso del previsto.

    La regola ha una seconda metà, più strana, che quasi nessuno conosce. Cron non verifica se un campo di giorno è vincolato; verifica se il primo carattere del campo è un asterisco. Un passo come */14 conta quindi come asterisco benché vincoli il campo all’1, al 15 e al 29 — e la sua presenza riporta i due campi di giorno dall’«o» alla «e». Due espressioni che sembrano vincolate allo stesso modo si comportano allora in modo del tutto diverso, e questo strumento segnala quale regola è in vigore.

    Quartz e EventBridge evitano l’intera questione rifiutando che entrambi i campi dicano qualcosa: esattamente uno dei due deve essere un punto interrogativo, che significa «nessun valore specifico, decide l’altro campo».

    Passi che non dividono il proprio campo

    Un passo si scrive come se fosse un intervallo, e dentro un ciclo del campo lo è. Attraversando il confine, di solito no.

    */7 nel campo delle ore significa le ore 0, 7, 14 e 21. Dopo le 21 il campo finisce, quindi l’esecuzione successiva è alle 0 del giorno dopo: tre ore dopo, non sette. Ogni ciclo termina con un intervallo corto, e lo stesso succede con */7 nei minuti (un buco di quattro minuti dopo il 56) e con qualsiasi altro passo che non divida il proprio intervallo in modo esatto. */15 nei minuti e */6 nelle ore sono sicuri; la maggior parte dei numeri a cui si pensa non lo è.

    Questo conta quando il passo è scelto per distribuire lavoro. Un job su */7 ore non gira ogni sette ore, e un limite di frequenza dimensionato per sette verrà superato una volta al giorno.

    I giorni della settimana sono numerati diversamente a seconda del posto

    Vixie cron numera i giorni da 0 a 7 con la domenica a entrambe le estremità, così 0 e 7 sono lo stesso giorno e 1 è lunedì. Quartz e EventBridge li numerano da 1 a 7 con la domenica a 1, quindi lì 1 è domenica e 2 è lunedì.

    Un’espressione copiata da una configurazione Quartz in un crontab gira dunque un giorno in anticipo, e da nessuna parte qualcosa protesta, perché entrambe le scritture sono numeri validi in entrambi i sistemi. I nomi di tre lettere — MON, FRI — significano lo stesso giorno ovunque e sono la difesa semplice.

    L’ora legale: le due mattine dell’anno

    Un demone cron non pianifica istanti. Guarda l’orologio locale ogni minuto e chiede se l’espressione combacia. Due volte l’anno quell’orologio non è una successione beneducata.

    Quando salta in avanti, un’ora di letture non accade mai. Un job impostato alle 02:30 non ha alcun 02:30 quel giorno. Quando torna indietro, un’ora di letture accade due volte, e un job impostato all’01:30 ne ha due.

    Vixie cron distingue qui due tipi di job, e la distinzione vale la pena di essere conosciuta perché decide quali dei tuoi job siano toccati. Un job fissato a un’ora dell’orologio — ora e minuto fissi — viene eseguito esattamente una volta in entrambi i casi: dopo un salto in avanti parte subito, e dopo un ritorno indietro cron si cura di non ripeterlo. Un job con un asterisco nell’ora o nel minuto è un job a intervallo e segue semplicemente l’orologio: perde un’ora di esecuzioni in primavera e ne ripete una in autunno.

    Così un backup orario gira davvero due volte in una notte l’anno, e un job notturno alle 02:30 gira davvero in un momento insolito in un’altra notte. Questo strumento confronta i prossimi dodici mesi del fuso scelto con la tua espressione e dice quale dei due casi si applica, con la data.

    La via d’uscita affidabile è pianificare il job in UTC, oppure fuori dalla fascia locale 01:00–03:00, dove non cade alcun cambio.

    Su quale orologio si trova davvero il job

    Un crontab gira nel fuso locale della macchina, o in quello indicato da CRON_TZ o TZ in cima al file. Raramente è il fuso di chi legge l’espressione, ed è per questo che qui il fuso orario è un’impostazione e non quello del tuo browser.

    Un CronJob di Kubernetes è ancora un’altra cosa: legge la sua pianificazione in UTC a meno che il manifest non imposti un campo timeZone, qualunque cosa dica l’orologio del nodo. Una pianificazione scritta per l’orario d’ufficio locale e distribuita senza quel campo gira all’ora sbagliata ovunque fuori da UTC — e non cambia con le stagioni, il che è un bug o un sollievo a seconda del job.

    Jenkins e l’H

    Jenkins aggiunge un simbolo che nessun altro dialetto ha: H, che sembra casualità e non lo è. Jenkins fa l’hash del nome del job in un valore fisso dentro l’intervallo del campo, così il job gira alla stessa ora ogni giorno — la propria — mentre cento job scritti H * * * * si distribuiscono uniformemente sull’ora invece di partire tutti al minuto zero.

    Poiché il valore viene dal nome del job, e il nome non fa parte dell’espressione, nessuno strumento può calcolare gli orari esatti. Questo risolve ogni H in fondo al suo intervallo e lo dichiara: la forma della pianificazione — ogni quanto, in quali giorni — è esatta, e solo lo scostamento dentro ciascun periodo è un sostituto.

    Jenkins ridefinisce anche le macro. Il suo @daily è @midnight, che non è mezzanotte ma un minuto scelto per hash da qualche parte nelle prime tre ore del giorno.

    Quello che cron non fa

    • Non recupera. Se la macchina dormiva o il demone era fermo quando un’esecuzione era prevista, quell’esecuzione non avviene più tardi: viene semplicemente persa. anacron esiste esattamente per questo ed è un altro programma.
    • Non impedisce esecuzioni sovrapposte. Se un job dura più dell’intervallo, il successivo parte comunque, e dopo un po’ ce ne sono diversi. Un file di lock è la risposta consueta.
    • Nella forma classica non ha nozione di secondi. La risoluzione più fine è un minuto; qualcosa di più rapido richiede Quartz, systemd o un ciclo dentro il job stesso.
    • @reboot non è una pianificazione. Gira una volta all’avvio del demone, quindi non ha una prossima esecuzione, e su una macchina che non si riavvia mai non gira affatto.
    • Un’espressione rate in EventBridge conta dal momento in cui la regola è stata creata, e quel momento non è nell’espressione: nessuno strumento può quindi dire quando scatterà.

    Domande frequenti

    Come faccio a eseguire un job il primo lunedì del mese?
    Non con una semplice espressione cron: servirebbe una «e» fra i due campi di giorno, e cron dà una «o». L’aggiramento consueto è pianificare 0 0 1-7 * * e far controllare il giorno della settimana al comando stesso. Quartz e EventBridge sanno esprimerlo direttamente, come 0 0 12 ? * MON#1.
    Perché 0 0 13 * 5 gira così spesso?
    Perché significa il 13 oppure ogni venerdì, non venerdì 13. Quando entrambi i campi di giorno sono vincolati e nessuno comincia con un asterisco, cron esegue il job quando ne combacia uno qualsiasi. Nel dialetto classico non c’è modo di scrivere una «e».
    Che differenza c’è fra */5 e 0-59/5?
    Nessuna, per il campo dei minuti: entrambi danno 0, 5, 10 e così via. La differenza salta fuori nei due campi di giorno, dove cron decide fra «e» e «o» guardando se il campo comincia con un asterisco — quindi */5 e 0-59/5 selezionano gli stessi giorni ma si combinano diversamente con l’altro campo di giorno.
    Il mio job gira due volte quando l’orologio torna indietro?
    Se ha un asterisco nell’ora o nel minuto, sì: segue l’orologio, e quell’ora capita due volte. Se ha ora e minuto fissi, no — Vixie cron esegue un job così una volta sola. Il pannello dei rilievi dice quale sia il tuo caso, con la data in cui si applica.
    Quale fuso orario usa un’espressione cron?
    Quello della macchina, a meno che CRON_TZ o TZ non siano impostati nel crontab. Un CronJob di Kubernetes usa UTC a meno che il manifest non imposti timeZone. Poiché il fuso non fa parte dell’espressione, questo strumento lo chiede invece di dare per scontato quello del tuo browser.
    Posso pianificare qualcosa ogni 90 minuti?
    Non come una sola espressione, perché ogni campo cicla per conto proprio e 90 minuti non stanno dentro un’ora. La scrittura consueta sono due espressioni, 0 0,3,6,9,12,15,18,21 * * * e 30 1,4,7,10,13,16,19,22 * * *, che insieme danno un’esecuzione ogni 90 minuti.
    Qualcosa di ciò che incollo viene inviato a un server?
    No. L’analisi, la spiegazione e tutto il calcolo della pianificazione girano nel tuo browser; nulla viene caricato o registrato, e funziona senza connessione di rete.