Sysadmin

Cron Job Linux: Guida Completa + 10 Esempi Pratici (2026)

Cron Job Linux: Guida Completa + 10 Esempi Pratici (2026)

Lunedì mattina. Apro la dashboard di monitoraggio dell’infrastruttura di un cliente nel settore healthcare. L’ultimo backup riuscito risale a venerdì sera. Il task notturno ha provato a girare per tutto il weekend, ma nessun dato è stato salvato. Lo script di backup funzionava perfettamente quando lo avevo lanciato manualmente venerdì pomeriggio. La differenza? L’ho eseguito dalla mia shell, non tramite cron. La mancanza di variabili d’ambiente adeguate ha fatto fallire la connessione al database in modo silenzioso.

Se amministri server Linux, i cron job sono il cuore pulsante delle operazioni automatiche: backup, rotazione log, check di sicurezza, sync di configurazioni. Purtroppo, l’ambiente di esecuzione di cron è volutamente minimale e questo genera problemi oscuri. In questa cron job linux guida, analizzo la sintassi, le differenze tra cron utente e di sistema, e le tecniche di debugging per capire esattamente perché un task schedulato smette di funzionare.

Cos’è un cron job e quando usarlo

Un cron job è un’attività pianificata gestita dal demone cron (crond su distribuzioni Red Hat based). Il demone si attiva ogni minuto, legge i file di configurazione e lancia i comandi la cui pianificazione corrisponde all’orario corrente. Usa i cron job per tutto ciò che richiede esecuzione ripetitiva e prevedibile: backup notturni, rinnovo di certificati Let’s Encrypt, pulizia di directory temporanee, invio di report.

Non usare cron per task che richiedono un controllo dipendenze complesso o che devono garantire l’esecuzione anche se il server era spento all’orario prestabilito. Per questi scenari, systemd timer offre funzionalità più avanzate.

Sintassi crontab spiegata campo per campo

Ogni riga in un file crontab contiene sei campi. I primi cinque definiscono la frequenza, il sesto specifica il comando da eseguire.

# Sintassi: minuto ora giorno mese giorno_settimana comando
0 2 * * * /backup/script.sh

I campi accettano numeri interi, asterischi (che indicano “ogni valore”), liste separate da virgola (1,15), range (1-5) e l’operatore passo (*/15 per indicare “ogni 15 unità”). Il campo giorno_settimana usa valori da 0 a 7, dove sia 0 che 7 indicano la domenica.

Esempi pratici di schedulazione (ogni minuto, ora, giorno, settimana)

Vediamo le configurazioni più richieste in produzione. Per eseguire un check ogni 15 minuti, usi l’operatore passo al campo minuto. Per un report lunedì mattina, specifichi il giorno della settimana.

*/15 * * * * /check/health.sh
0 9 * * 1 /weekly/report.sh

Se ti serve una configurazione di tipo cron ogni ora configurare, la sintassi corretta prevede il minuto specifico e l’asterisco sull’ora. Ad esempio, per lanciare uno script al minuto 0 di ogni ora:

0 * * * * /opt/scripts/hourly_check.sh

Per eseguire un comando ogni minuto, cosa utile durante i test iniziali, utilizzi cinque asterischi.

Modificare il crontab con crontab -e

Per modificare la tabella cron del tuo utente, il comando standard è crontab -e. Questo apre il file di configurazione nell’editor di default (di solito vi o nano). Se è la prima volta che lo esegui, il sistema ti chiederà di scegliere l’editor predefinito.

crontab -e

Per visualizzare le regole attive senza aprire l’editor, usi crontab -l. Ti consiglio di eseguire sempre un backup della configurazione prima di modificarla redirigendo l’output su un file.

crontab -l > ~/crontab_backup_$(date +%F).txt

Cron di sistema vs cron utente (/etc/cron.d, /etc/crontab)

Esiste una differenza fondamentale tra il crontab utente e quello di sistema. Il crontab utente, gestito con il comando crontab, non specifica l’utente di esecuzione perché gira con i privilegi dell’utente che lo ha creato.

I file in /etc/cron.d/ e il file /etc/crontab appartengono al sistema e contengono un sesto campo prima del comando: l’utente che deve eseguire il task.

# Esempio in /etc/crontab
0 3 * * * root /usr/local/bin/maintenance.sh

In ambienti enterprise, preferisco usare /etc/cron.d/ per i task di sistema. Permette di distribuire singoli file con Ansible o script di provisioning senza toccare il crontab globale, riducendo il rischio di sovrascritture.

Variabili d’ambiente nei cron job (PATH, MAILTO)

Qui si nasconde il problema che mi ha fatto perdere più ore in produzione. Cron non carica il profilo utente. Non esegue .bashrc, .profile o simili. L’ambiente è ridotto all’osso. La variabile PATH spesso è limitata a /usr/bin:/bin.

Se il tuo script usa comandi in /usr/sbin/ (come iptables) o in /usr/local/bin/ (come comandi personalizzati o Python pip), il cron job fallirà con un “command not found” silente.

Imposta sempre il PATH all’inizio del file crontab:

PATH=/usr/local/bin:/usr/bin:/bin

La variabile MAILTO definisce dove inviare l’output del comando. Di default, cron manda un’email all’utente proprietario del cron job. Se il server non ha un MTA configurato, l’output viene perso. Imposta MAILTO=”” per disabilitare l’invio, ma assicurati di reindirizzare l’output su un file di log.

Reindirizzare output e log dei cron

Un cron job eseguito senza reindirizzamento invia tutto l’output (sia lo standard output che lo standard error) via email. Nella maggior parte dei server moderni, questa email finisce in /var/mail/$USER o viene scartata. Per tracciare cosa succede, devi catturare i log su file.

* * * * * /script.sh >> /var/log/myscript.log 2>&1

Il costrutto 2>&1 reindirizza lo standard error (file descriptor 2) nello stesso posto dello standard output (file descriptor 1). Il doppio maggiore (>>) aggiunge i dati al file senza sovrascriverlo. Se usi un singolo maggiore (>), cancelli il log precedente a ogni esecuzione, perdendo la storia.

Verificare se un cron è stato eseguito

Non fidarti del fatto che lo script abbia prodotto l’effetto atteso. Verifica il log di sistema per confermare che il demone cron abbia effettivamente lanciato il processo. Su distribuzioni Debian/Ubuntu, cron logga le azioni in /var/log/syslog. Su RHEL/CentOS, usa /var/log/cron.

Cerca la stringa CMD per vedere i comandi eseguiti o la stringa CRON per i messaggi generici del demone.

Errori comuni — PATH mancante, permessi, script non eseguibile

Il problema del cron non funziona debug quasi sempre riconduce a uno di questi quattro errori.

Il primo è il PATH incompleto, come abbiamo visto. Usa percorsi assoluti per ogni singolo binario nel tuo script.

Il secondo riguarda i permessi. Se crei uno script e lo lanci con bash script.sh funziona, ma se lo chiami direttamente in cron (/script.sh) richiede il bit di esecuzione. Esegui chmod +x /script.sh.

Il terzo errore riguarda i ritorni a capo in stile Windows (CRLF). Se modifichi lo script su una macchina Windows e lo carichi su Linux, cron non riesce a interpretare correttamente lo shebang (#!/bin/bash). Il risultato è un errore “bad interpreter”. Converti il file con dos2unix o imposta il formato LF nel tuo editor.

Il quarto è la mancanza del ritorno a capo finale. L’ultima riga del file crontab deve terminare con un carattere di a capo. Senza, cron potrebbe ignorare l’ultima regola.

Debugging con syslog e journalctl

Quando un task non parte e non hai log applicativi, devi ispezionare i log di sistema. Su sistemi con syslog tradizionale, filtra i messaggi del demone.

grep CRON /var/log/syslog

Se il tuo server usa systemd, il servizio cron registra gli eventi nel journal. Puoi interrogarlo specificamente per l’unità cron.

journalctl -u cron

Aggiungi l’opzione -f per seguire i log in tempo reale mentre attendi l’esecuzione programmata del task, e –since “1 hour ago” per limitare l’output.

[Leggi anche: Trovare e liberare spazio su disco in Linux]

Alternativa moderna: systemd timer

Per nuove implementazioni complesse, valuto sempre systemd timer al posto di cron. I timer offrono vantaggi concreti in infrastrutture critiche. Il parametro Persistent=true garantisce che un task venga eseguito anche se il server era spento all’orario previsto, recuperandolo al prossimo avvio.

Inoltre, i timer si integrano nativamente con journalctl per il logging e permettono di definire dipendenze esplicite (ad esempio, esegui il backup solo dopo che il mount della rete è attivo).

La sintassi richiede due file: un .service per definire il comando e un .timer per definire la schedulazione. Puoi verificarne lo stato con systemctl list-timers.

Per i task semplici e lineari, cron rimane lo strumento più rapido. Per architetture con centinaia di VM dove l’affidabilità e la tracciabilità sono obbligatorie, systemd timer riduce gli incidenti silenziosi.

Riferimenti ufficiali sulla configurazione e i formati supportati sono disponibili nella documentazione di crontab su man7.org: https://man7.org/linux/man-pages/man5/crontab.5.html

Condividi questo articolo:

Scritto da

Rosario Giordano

Rosario Giordano è System Administrator e consulente IT specializzato in cybersecurity e cloud, con oltre 20 anni di esperienza nella gestione di infrastrutture Linux enterprise. Le sue aree di competenza includono hardening di SSH, piattaforme Kubernetes, database PostgreSQL, ambient i virtualizzati VMware e Proxmox, nonché la conformità ai framework di sicurezza NIS2 e ISO 27001.