Spiegazione dell'espressione Cron
Incolla un'espressione cron e capisci esattamente cosa fa.
Esempi comuni
Come leggere le espressioni cron
Un'espressione cron standard ha 5 campi separati da spazi:
minuto ora giorno mese giorno-settimana
* · qualsiasi valore */n · ogni n unità 1,5 · ai valori 1 e 5 1-5 · intervallo da 1 a 5
Intervalli: minuto (0-59), ora (0-23), giorno (1-31), mese (1-12), giorno settimana (0-6, 0 = domenica)
Come funziona
- Inserisci un'espressione cron: incolla una stringa cron a 5 o 6 campi come
0 9 * * 1-5. - Leggi la spiegazione in linguaggio naturale: lo strumento mostra immediatamente una descrizione leggibile di quando il job viene eseguito.
- Visualizza i prossimi tempi di esecuzione: viene mostrata una lista delle prossime 5–10 esecuzioni programmate in base alla data e ora correnti.
- Convalida: le espressioni non valide vengono evidenziate con messaggi d'errore specifici che spiegano cosa non va.
Mezzo secolo di tick al minuto
Cron è lo scheduler più vecchio ancora in uso quotidiano continuo sulla maggior parte dei server del mondo. La sua prima apparizione nei registri storici è il maggio 1975, quando una versione iniziale fu distribuita dai Bell Laboratories di AT&T come parte del ramo Research Unix. Il nome è un cenno a Chronos, la personificazione greca del tempo, e il design è invecchiato con strana grazia: gli stessi cinque campi separati da spazi che gli ingegneri di Bell Labs digitavano in /usr/lib/crontab a metà degli anni '70 guidano ancora i CronJob di Kubernetes, gli schedule di GitHub Actions e il backup notturno del database su un server virtuale privato da qualche parte a Francoforte in questo momento. L'implementazione del 1975 era minimale: c'era un crontab, di proprietà di root, che serviva l'intera macchina. Se un utente voleva un job ricorrente, chiedeva all'amministratore di aggiungere una riga a mano. Cron viaggiò nel mondo più ampio in Unix Versione 7, rilasciata nel 1979. Robert Brown e Keith Williamson alla Purdue University estesero cron per gestire più utenti alla fine del 1979, introducendo il workflow crontab -e per utente. La riscrittura decisiva arrivò quando Paul Vixie rilasciò vixie-cron 1.0 il 6 maggio 1987; vixie-cron formalizzò i caratteri speciali e introdusse le scorciatoie @reboot, @hourly, @daily, @weekly, @monthly, @yearly. Vixie 3.0 (27 dicembre 1993) aggiunse i valori di passo (/) e si distribuì, con piccole patch, in quasi ogni distribuzione Linux e BSD dell'epoca. POSIX si mise in pari nel 1992 (IEEE Std 1003.2-1992). Ogni stranezza del cron moderno (la numerazione domenica off-by-one, il bug union-vs-intersection del campo giorno) è una cicatrice di questa evoluzione; nulla di tutto ciò fu progettato in una singola seduta.
Anatomia di un'espressione a cinque campi
Un'espressione cron standard è cinque campi separati da spazi. Letti da sinistra a destra, chiedono: quale minuto, di quale ora, di quale giorno del mese, di quale mese, di quale giorno della settimana? Gli intervalli esatti non sono negoziabili in POSIX cron: minuto 0-59, ora 0-23, giorno-del-mese 1-31, mese 1-12, giorno-della-settimana 0-7 con sia 0 sia 7 che rappresentano la domenica. Ogni campo accetta cinque operatori che si compongono liberamente: * significa ogni valore valido; , separa una lista di valori discreti (0,15,30,45 * * * * gira a inizio, e quarto, mezza, tre quarti di ogni ora); - è un intervallo inclusivo (9-17 nel campo ora significa 9, 10, 11, 12, 13, 14, 15, 16, 17); / è un valore di passo (*/15 nel campo minuto significa ogni quindicesimo minuto a partire da zero, cioè 0, 15, 30, 45). I mesi e i giorni-della-settimana possono anche essere scritti come abbreviazioni di tre lettere: JAN-DEC e SUN-SAT. Un esempio risolto: */15 9-17 * * 1-5 si decodifica come ogni quindici minuti durante le ore da 9 a 17 incluse, in ogni giorno del mese, ogni mese dell'anno, dal lunedì al venerdì: "ogni quarto d'ora durante le ore lavorative nei giorni feriali."
La trappola giorno-del-mese / giorno-della-settimana
La stranezza più consequente di cron, quella che ha causato outage, backup mancati e fatture quietamente sbagliate in produzione per trentacinque anni, è il modo in cui cron combina i campi giorno-del-mese e giorno-della-settimana quando entrambi sono ristretti. Il linguaggio POSIX è insolitamente preciso qui: "se sia 'giorno del mese' (campo 3) sia 'giorno della settimana' (campo 5) sono ristretti (non contengono '*'), allora uno o entrambi devono coincidere col giorno corrente." In altre parole, quando nessuno dei due campi è wildcard, cron prende l'unione dei due: il job gira in qualsiasi giorno che corrisponda a una delle due restrizioni. Questo è l'opposto di ciò che la maggior parte degli utenti assume. Leggere 0 0 13 * 5 ad alta voce, "mezzanotte del 13, di venerdì", suona naturalmente come un'intersezione: solo venerdì 13. In vixie-cron e nei suoi discendenti significa effettivamente "ogni 13 del mese e ogni venerdì", scattando circa nove volte al mese. Peggio, vixie-cron decide se usare unione o intersezione ispezionando solo il primo carattere di ogni campo giorno. Paul Vixie stesso ha riconosciuto il comportamento come bug ma si è rifiutato di cambiarlo, notando che ripararlo violerebbe il principio della minor sorpresa: milioni di crontab erano già scritti sull'assunzione che il comportamento esistente fosse deliberato. Il bug è quindi ora una caratteristica, immortale e propagante. Il modello mentale pragmatico: se ti trovi a restringere sia giorno-del-mese sia giorno-della-settimana e vuoi effettivamente l'intersezione (es. "il secondo martedì di ogni mese"), usa l'operatore # nelle implementazioni che lo supportano (Quartz, cronie con estensioni): 0 12 ? * 2#2. In POSIX cron puro, l'intersezione è genuinamente impossibile da esprimere in una singola espressione e devi filtrare dentro lo script che il job cron invoca.
Le macro di scorciatoia
@yearly/@annually=0 0 1 1 *: mezzanotte, 1° gennaio@monthly=0 0 1 * *: mezzanotte, primo di ogni mese@weekly=0 0 * * 0: mezzanotte, domenica@daily/@midnight=0 0 * * *: mezzanotte ogni giorno@hourly=0 * * * *: scoccare di ogni ora@reboot: speciale, scatta una volta quando il demone cron parte (non una volta per riavvio del sistema: su sistemi dove cron può essere fermato e riavviato,@rebootscatterà di nuovo)
Queste scorciatoie non sono POSIX. Gli ambienti strettamente POSIX-only rifiuteranno @daily; in pratica ogni implementazione di cron che un lettore probabilmente incontrerà (vixie-cron, cronie, fcron, ISC cron, immagini container) le supporta.
I dialetti: standard contro Quartz contro AWS contro K8s contro systemd
L'"espressione cron" è ora una piccola famiglia di dialetti mutuamente incompatibili. Cron standard a 5 campi (POSIX, vixie-cron, cronie): minuto ora giorno-del-mese mese giorno-della-settimana: il minimo comune denominatore universale. Quartz Scheduler (6 o 7 campi, ecosistema Java): secondi minuti ore giorno-del-mese mese giorno-della-settimana [anno]; introduce ?, L (last), W (weekday), # (n-esimo weekday del mese). @Scheduled di Spring e Spring Boot usano Quartz. Kubernetes CronJob usa cron standard a 5 campi, con un campo separato spec.timeZone che è andato GA in K8s 1.27 (la risorsa CronJob stessa è stata GA in 1.21, aprile 2021); il formato del fuso orario è il database tz IANA (Europe/Berlin, America/New_York). Gli schedule cron di GitHub Actions usano cron POSIX a 5 campi e girano in UTC. AWS EventBridge cron usa 6 campi (minuti ore giorno-del-mese mese giorno-della-settimana anno), richiede l'operatore ? sul giorno-del-mese o sul giorno-della-settimana (non puoi restringere entrambi), e usa 1-7 con SUN=1: significando che un'espressione EventBridge 0 12 ? * 2 * gira a mezzogiorno il lunedì, non il martedì. I timer systemd usano una sintassi del tutto diversa (OnCalendar=*-*-* 02:00:00) e stanno gradualmente sostituendo cron sul Linux moderno per lo scheduling a livello di sistema, anche se entrambi si distribuiscono fianco a fianco su ogni distro principale. Cloud Scheduler (Google Cloud) usa cron standard a 5 campi con configurazione esplicita del fuso orario. Tradurre espressioni tra piattaforme richiede attenzione attenta: uno schedule EventBridge incollato girerà sul giorno della settimana sbagliato in vixie-cron a causa dello shift di numerazione del giorno-della-settimana.
Pattern comuni che vale la pena memorizzare
*/15 * * * *: ogni 15 minuti (00:00, 00:15, 00:30, 00:45 di ogni ora)*/15 9-17 * * 1-5: ogni 15 minuti durante le ore lavorative, solo nei giorni feriali0 9 * * 1-5: ogni giorno feriale alle 90 6,18 * * *: due volte al giorno, alle 6 e alle 18 (usando una lista, non un intervallo)0 0 1 * *: mezzanotte del 1° di ogni mese0 0 L * *: mezzanotte dell'ultimo giorno di ogni mese (Lè un'estensione Quartz/cronie)0 3 1-7 * 1: primo lunedì di ogni mese alle 3 (usa il bug dell'unione deliberatamente: corrisponde ai giorni 1-7 E ai lunedì, ma gli unici giorni che soddisfano entrambe le restrizioni in un mese qualsiasi sono il primo lunedì)0 0 1 1,4,7,10 *: mezzanotte del primo giorno di ogni trimestre del calendario0 0 * * 0,6: mezzanotte nei fine settimana
Trabocchetti comuni
Fuso orario. cron usa l'ora locale del sistema di default: sorprendente sulle macchine cloud che predefiniscono a UTC. Un job cron alle 9 su un server UTC scatta alle 4 dell'Eastern. Gli scheduler moderni (Kubernetes 1.27+, AWS EventBridge, Cloud Scheduler) hanno aggiunto campi espliciti di fuso orario; cron classico no. La regola "*/N inizia da 0". */15 è 0, 15, 30, 45, non 5, 20, 35, 50. Per iniziare con offset diverso da zero devi enumerare (5,20,35,50) o usare la sintassi 5/15 solo Quartz. La trappola dell'accumulo a 60 minuti. Un job che impiega più dell'intervallo del suo schedule può accumularsi: tre backup da 30 minuti che scattano ogni 15 minuti si sovrapporranno. La mitigazione standard è flock(1): * * * * * /usr/bin/flock -n /tmp/myjob.lock /path/to/myjob garantisce che giri solo un'istanza alla volta; il flag -n rende l'acquisizione del lock non bloccante, così che le invocazioni successive escano silenziosamente invece di mettersi in coda. Anomalie DST. Un job cron schedulato alle 02:30 scatterà due volte il giorno in cui gli orologi tornano indietro e per niente il giorno in cui vanno avanti. cron non ha alcun concetto di "ora wall-clock che tiene conto del DST"; se il tuo schedule deve saltare le transizioni DST, ancoralo a un'ora non interessata (le 3 o oltre nella maggior parte dei fusi) o usa uno scheduler che capisca la semantica del fuso orario. Sottrazione del PATH. I job cron girano con un PATH minimale (/usr/bin:/bin) e un ambiente quasi vuoto; gli script che funzionano nella tua shell interattiva possono fallire in cron perché node, python3 o aws non sono nel PATH ereditato. O imposta PATH= in cima al crontab o usa percorsi assoluti nel comando cron. Esubero di email. Di default cron invia per email l'output di ogni job alla casella di posta locale dell'utente; su un server senza posta configurata questo riempie silenziosamente /var/spool/mail finché il disco non si esaurisce. O reindirizza l'output (>/dev/null 2>&1), imposta MAILTO="" in cima al crontab, o configura effettivamente un forwarder di posta.
Alternative moderne: quando ricorrere a qualcos'altro
cron è eccellente per task ricorrenti semplici su una singola macchina. È povero in: scheduling distribuito (lo stesso job innescato una volta su una flotta invece di una volta per macchina), trigger event-driven (gira quando una coda riceve un messaggio, non su un orologio), monitoring (cron fallisce silenziosamente se il job esce con codice diverso da zero a meno che non si configuri il forwarding email), retry (nessun meccanismo integrato: i job falliti girano di nuovo nel ciclo successivo e accumulano stato), e dipendenze (gira il job B solo dopo che il job A è completato con successo). Per quei casi la risposta moderna è una di: Kubernetes CronJob (scheduling cluster-aware con policy di retry e parallelismo), AWS EventBridge + Lambda o Step Functions (event-driven con osservabilità integrata), Apache Airflow o Prefect (orchestrazione di workflow basata su DAG con dipendenze esplicite), Temporal (esecuzione di workflow durevole), healthchecks.io (un "interruttore di sicurezza" che ti pinga quando un job cron non gira come previsto). Per job ricorrenti su una sola macchina nel 2026, plain cron è ancora la risposta giusta; per qualsiasi altra cosa, una delle alternative vale il setup extra.
Domande frequenti
Cosa significa * in un'espressione cron?
Un asterisco (*) in un campo cron significa "ogni valore valido": ogni minuto, ogni ora, ogni giorno, ogni mese, ogni giorno-della-settimana. * * * * * gira ogni minuto di ogni giorno. L'asterisco è anche speciale nei campi giorno-del-mese e giorno-della-settimana per via della trappola unione-contro-intersezione: quando uno dei due campi giorno ha un * iniziale, vixie-cron usa la modalità intersezione; quando nessuno dei due ce l'ha, usa la modalità unione e gira sull'unione di entrambe le restrizioni.
Come faccio a far girare un job cron ogni 15 minuti?
Usa la notazione di passo: */15 * * * * gira ogni 15 minuti, alle xx:00, xx:15, xx:30 e xx:45. Nota che */N inizia sempre da 0; non puoi usare */15 per significare "ogni 15 minuti partendo dal minuto 5": per quello scriveresti 5,20,35,50 * * * *. Il dialetto cron Quartz supporta 5/15 come alternativa non standard.
Qual è la differenza tra cron e at?
cron esegue job su uno schedule ricorrente (ogni minuto, ogni giorno, ogni settimana). Il comando at programma un job una tantum da eseguire a un momento futuro specifico: at 14:30 tomorrow mette in coda un job per quel singolo momento. Usa cron per task ricorrenti e at per esecuzioni future una tantum. Entrambi discendono dalla stessa stirpe Bell Labs / vixie-cron e alla fine furono integrati nello stesso demone sulla maggior parte dei sistemi.
Perché il mio job cron non corrisponde a ciò che mi aspettavo?
Le cinque cause più comuni, in ordine di frequenza approssimativo: (1) Confusione tra giorno-del-mese e giorno-della-settimana: cron usa l'unione di entrambi quando entrambi sono ristretti, non l'intersezione. (2) Fuso orario: cron usa l'ora locale del server di default, spesso UTC sulle macchine cloud. (3) Problemi di PATH: il PATH della tua shell interattiva non è ereditato, quindi i comandi che funzionano al prompt possono fallire in cron. (4) La trappola del */N che inizia sempre da 0. (5) Output non catturato da nessuna parte: i job falliti scompaiono silenziosamente se non hai configurato l'email o reindirizzato l'output a un file di log. Il pannello "prossime 10 esecuzioni programmate" di questo spiegatore è il modo più economico per verificare cosa significa effettivamente la tua espressione prima del deploy.
Supporta formati cron non standard?
Gestisce cron POSIX/vixie-cron standard a 5 campi, la variante Quartz/Spring a 6 campi con secondi, e le stringhe speciali @hourly, @daily, @weekly, @monthly, @yearly e @reboot. Non gestisce le estensioni Quartz complete (L, W, #) né la numerazione weekday 1-based di AWS EventBridge: per quelli, usa il validatore proprio della piattaforma prima del deploy.
La mia espressione cron viene inviata da qualche parte?
No. Il parsing e la spiegazione girano interamente nel tuo browser tramite JavaScript. Le espressioni incollate non attraversano mai la rete: verifica nel pannello Network di DevTools mentre clicchi Spiega. Sicuro per espressioni cron in config CI di produzione, codice di infrastruttura e runbook operativi dove lo schedule stesso potrebbe essere sensibile (es. schedule di export notturno del database che suggeriscono finestre di downtime).