Corso Linux / Pianificare attività con cron e timer systemd

Cron è adatto a pianificazioni semplici; i timer systemd integrano invece gli orari con lo stato dei servizi e i log. Verifica separatamente l'interpretazione dell'orario, l'esecuzione reale, l'output e gli errori: la registrazione di un'attività non dimostra che sia riuscita.

Prima di pianificarlo, esegui direttamente il comando come nel primo script Bash. Per i timer utente verifica nella macchina virtuale il ciclo di vita del gestore systemd dopo il logout e la configurazione di linger, che può mantenerlo attivo senza una sessione aperta. La sola registrazione non garantisce l'esecuzione continua.

Gli ambienti di riferimento del corso sono macchine virtuali con installazioni convenzionali di Ubuntu 26.04 LTS o Rocky Linux 9. Container, WSL e altre versioni possono avere servizi e pacchetti diversi. Prepara l'accesso alla console per il recupero e annota le versioni, seguendo la lezione sull'ambiente di laboratorio in macchina virtuale (in inglese). Le istruzioni seguenti richiedono un sistema Linux con gestore systemd utente disponibile; la sola verifica della sintassi in Git Bash su Windows non verifica timer, journal o logout.

Scegliere tra cron e un timer systemd

Criterio cron tradizionale Timer systemd
Configurazione Campi temporali e comando su una riga Unità timer e service separate
Controllo Output e log dipendenti dalla distribuzione Stato del servizio e journal
Ambiente Ambiente diverso dalla shell interattiva Ambiente definito per l'unità
Esecuzioni perse In genere non recuperate automaticamente Valutare OnCalendar e Persistent

Nomi dei servizi, pacchetti e implementazioni dipendono dall'installazione. Su Ubuntu puoi incontrare il pacchetto cron; su Rocky Linux sono comuni cronie e il servizio crond, descritti nella guida ufficiale alle attività cron di Rocky Linux. Controlla ciò che è installato e il manuale locale: un'implementazione come systemd-cron può tradurre i crontab in unità e non equivale al demone cron tradizionale. Distingui anche cron da strumenti complementari come anacron, che hanno proprie regole per i lavori periodici.

Leggere i campi cron e il contesto di esecuzione

crontab -e modifica le attività dell'utente corrente. Nel formato utente i cinque campi temporali di Cronie sono minuto, ora, giorno del mese, mese e giorno della settimana; segue il comando. L'esempio indica le 02:15 di ogni giorno secondo il fuso usato dal servizio. È soltanto un modello: sostituisci /home/USER con i percorsi assoluti effettivi e crea prima lo script e una destinazione scrivibile per il log. In /etc/crontab compare anche il campo utente prima del comando: non copiarlo nel crontab personale.

15 2 * * * /bin/bash /home/USER/bin/job.sh >> /home/USER/job.log 2>&1

Cron non eredita invariati PATH, directory corrente e variabili del terminale interattivo. Usa percorsi assoluti, imposta nello script la directory di lavoro e non inserire segreti nel testo del crontab. >> aggiunge l'output al log e 2>&1 vi indirizza anche gli errori; se non puoi aprire il log, il comando può non partire. Prevedi una rotazione dei log per un lavoro duraturo.

Quando giorno del mese e giorno della settimana sono entrambi limitati, Cronie applica una condizione OR: basta che corrisponda uno dei due. Verifica nel manuale della tua implementazione le regole su fuso orario e ora legale. Le ore inesistenti o ripetute possono influire sull'esecuzione. Anche % ha un significato speciale nel comando di crontab: in Cronie, se non protetto con una barra inversa, separa il comando dall'input standard e i successivi diventano nuove righe. Le virgolette della shell da sole non eliminano questa interpretazione di cron.

Creare le unità utente service e timer

Prima controlla con systemctl --user cat linux-course-clock.service linux-course-clock.timer se esistono unità con questi nomi, anche in percorsi diversi dalla directory locale. Verifica inoltre l'assenza dei due file indicati qui sotto, inclusi eventuali collegamenti simbolici. Se trovi una definizione esistente, fermati e scegli un nome diverso in tutti i comandi e nei due file; non sovrascriverla. Un errore di collegamento al gestore utente non dimostra che il nome sia libero.

L'esempio scrive un timestamp nel journal ogni minuto, senza creare un servizio di sistema né richiedere root. Esegui command -v date e prova /usr/bin/date --iso-8601=seconds direttamente. Se il percorso è diverso, adegua ExecStart. I blocchi devono essere eseguiti una riga alla volta controllando il risultato: non hanno una catena che arresta tutte le operazioni al primo errore. Se la creazione o la verifica dei file falliscono, non attivare il timer.

mkdir -p "$HOME/.config/systemd/user"
cat > "$HOME/.config/systemd/user/linux-course-clock.service" <<'EOF'
[Unit]
Description=Linux course timestamp exercise

[Service]
Type=oneshot
ExecStart=/usr/bin/date --iso-8601=seconds
EOF
cat > "$HOME/.config/systemd/user/linux-course-clock.timer" <<'EOF'
[Unit]
Description=Run the course clock every minute

[Timer]
OnCalendar=*-*-* *:*:00
AccuracySec=1s
Persistent=true

[Install]
WantedBy=timers.target
EOF
systemd-analyze calendar '*-*-* *:*:00'
systemctl --user daemon-reload
systemctl --user enable --now linux-course-clock.timer

Il timer attiva per impostazione predefinita il servizio con lo stesso nome di base. OnCalendar=*-*-* *:*:00 indica ogni minuto al secondo zero; systemd-analyze calendar deve mostrare l'espressione normalizzata e le prossime occorrenze, non avvia il lavoro. AccuracySec=1s definisce una finestra di tolleranza per raggruppare le attivazioni, non garantisce l'esecuzione in tempo reale entro un secondo in tutte le condizioni.

Con Persistent=true, applicabile ai timer OnCalendar, systemd conserva lo stato necessario per rilevare se durante l'inattività è stata persa almeno un'attivazione e può avviare il servizio alla riattivazione. Non riproduce una per una tutte le occorrenze perse e non è una garanzia di risveglio del computer. Il comportamento dipende anche dall'effettivo avvio del gestore utente e dalla correttezza dell'orologio.

Controllare la prossima attivazione e il risultato reale

systemctl --user list-timers --all linux-course-clock.timer
systemctl --user status linux-course-clock.timer
journalctl --user -u linux-course-clock.service --since "5 minutes ago" --no-pager
systemctl --user show linux-course-clock.service -p Result -p ExecMainStatus
timedatectl

Controlla il prossimo orario in list-timers; dopo uno o due minuti verifica nel journal il timestamp e i messaggi relativi al servizio. Un servizio Type=oneshot può tornare inactive dopo il successo: leggi anche Result e ExecMainStatus. Un valore di successo isolato può riferirsi all'ultima esecuzione precedente, quindi confrontalo con gli orari del journal e con il nuovo output atteso.

Se non trovi il risultato, verifica separatamente che i file siano stati caricati, il timer sia attivo, la prossima scadenza sia corretta e ExecStart funzioni nel contesto del servizio. timedatectl mostra fuso e sincronizzazione dell'orologio: confrontali con l'orario operativo desiderato. Controlla systemctl --version e il manuale della versione installata prima di usare opzioni tratte dalla documentazione di sviluppo.

Per lavori che devono continuare dopo il logout, verifica il ciclo di vita del gestore e la politica linger di loginctl, per esempio leggendo loginctl show-user "$USER" -p Linger. Abilitare linger può avviare il gestore al boot e mantenerlo dopo il logout; è una modifica alla politica del sistema, non un requisito da applicare alla cieca per questa prova. Il semplice enable del timer non dimostra il funzionamento dopo ogni logout o riavvio. Un timer di sistema operativo richiede inoltre un account dedicato, percorsi, privilegi minimi e limiti di risorse progettati appositamente.

Gestire sovrapposizioni ed errori e rimuovere la prova

Un lavoro cron più lungo del proprio intervallo può sovrapporsi alla successiva esecuzione; valuta un blocco come flock se disponibile e adatto. Quando scade un timer systemd e lo stesso servizio è già attivo, quel servizio resta in esecuzione: non viene riavviato né creata automaticamente una seconda istanza. Altre unità o avvii manuali possono comunque usare gli stessi dati, quindi rimangono necessari criteri di concorrenza dell'applicazione.

Per eliminare soltanto la prova, esegui prima la prima riga del blocco seguente. La disattivazione del timer impedisce nuove attivazioni ma non arresta necessariamente un servizio già partito: prima di rimuovere i file, controllalo e usa systemctl --user stop linux-course-clock.service per questa unità di laboratorio. Con il timer ormai fermo puoi rimuovere anche il timestamp di Persistent con systemctl --user clean --what=state linux-course-clock.timer, come indicato dal manuale systemd; verifica che il comando sia supportato dalla tua versione. Procedi poi con le righe rm, daemon-reload e la verifica finale.

systemctl --user disable --now linux-course-clock.timer
rm -- "$HOME/.config/systemd/user/linux-course-clock.timer" "$HOME/.config/systemd/user/linux-course-clock.service"
systemctl --user daemon-reload
systemctl --user list-timers --all linux-course-clock.timer

rm deve riguardare esclusivamente i due file creati da te. Dopo il ricaricamento non deve rimanere un'attivazione pianificata del timer rimosso; se appare ancora, controlla eventuali altre definizioni anziché cancellare file estranei. Se hai aggiunto la riga cron di esempio, rimuovi soltanto quella con crontab -e e verifica con crontab -l: non eliminare l'intero crontab. In produzione servono controlli separati che rilevino fallimenti e mancate esecuzioni, oltre a una procedura di recupero.

Documentazione ufficiale