Come configurare un processo cron (cronjob)

I processi cron sono estremamente utili per eseguire comandi automaticamente a tempi prestabiliti. Questa è una breve guida alla configurazione ed alla sintassi.

Il demone

Ci sono varie implementazioni di cron. Per questa guida useremo cronie, che integra l'originale crond e in più aggiunge il supporto a cronjob asincroni, utile per dispositivi che non rimangono perennemente accesi. Chi non può installare software ma ne ha una versione già installata può saltare allegramente alla prossima sezione, perché i comandi specificati sono (quasi) standard.

È installabile dai repo ufficiali di Fedora, Arch, openSUSE, Gentoo, Mandriva.

Avvio automatico

Per avviarlo con systemd esiste l'unità apposita cronie.service da abilitare:

$ sudo systemctl enable cronie
$ sudo systemctl start cronie

In alternativa basta eseguire crond -n dal vostro sistema di init.

Crontab: la configurazione

La sintassi dei crontab può sembrare oscura, ma in realtà è molto semplice.

Un crontab si sviluppa su 6 colonne, 5 che servono per stabilire il momento dell'esecuzione e l'ultima il comando da eseguire:

minuto ora giorno mese giorno_della_settimana comando

I valori supportati da ogni campo sono i seguenti:

minuto
tra 0 e 59
ora
tra 0 e 23
giorno
tra 1 e 31
mese
tra 1 e 12
giorno_della_settimana
tra 0 e 6, con 0 che parte dalla domenica
comando
percorso al comando. Sono usati PATH='/usr/bin:/bin' e /bin/sh come shell (di default)

Ci sono alcuni valori speciali standard che significano:

*
esegui per ogni possibile valore del campo
min-max
esegui per ogni possibile valore nel range specificato
a,b,c
esegui per un dato insieme di valori del campo
*/n
esegui per l'insieme di valori del campo multiplo di n, usato per esprimere un evento ricorrente

Vediamo alcuni esempi.

In questo caso sono specificati tutti *, quindi il comando sarà eseguito per ogni possibile valore disponibile. Avendo come unità minima il minuto, di conseguenza una volta al minuto. In questo caso scrivo l'output del comando date nel file ora della cartella dell'utente.

* * * * *  echo $(date) > ~/ora

In quest'altro caso invece si sfrutta l'operatore / per stabilire una periodicità sui minuti. Il comando in questo caso viene eseguito una volta ogni mezzora, e serve ad aggiornare un file meteo per un successivo script locale.

*/30 * * * *  curl http://wttr.in/?lang=it > ~/meteo

Un modo equivalente sarebbe:

0,30 * * * *  curl http://wttr.in/?lang=it > ~/meteo

Vediamo ora un esempio complesso che fa uso di tutte le possibili specifiche. Il comando è eseguito al minuto 0 ogni due ore di tutti i giorni di dicembre e gennaio, ma solo per i giorni feriali (1-5, 0 è domenica).

0 */2 * 1,12 1-5  comando_mega_utile_anzi_direi_cruciale.sh

Per essere più sicuri di aver scritto la giusta combinazione di operatori c'è un sito, crontab.guru, che spiega a parole il significato della dichiarazione. Può essere una sicurezza in più prima di rilasciare in produzione una tupla che non fa il suo lavoro.

Variabili d'ambiente

Se serve è possibile modificare le seguenti variabili d'ambiente all'inizio del file crontab:

  • HOME
  • LOGNAME
  • PATH
  • SHELL

Attenzione! Il file di configurazione non è interpretato da una shell, quindi non si può definire il PATH al solito modo (PATH=...:$PATH), perché il nuovo PATH non verrebbe interpolato. Di conseguenza bisogna esplicitamente dichiarare tutti i percorsi di interesse, separati da duepunti.

Ad esempio:

SHELL=/bin/ksh
HOME=/opt/
PATH=/opt/:/usr/bin/:/bin/

* * * * * ...

Come modificare il crontab

Capito il formato, è arrivato il momento di modificare il crontab.

Per elencare i cronjob già programmati esiste il comando:

$ crontab -l

Per modificare il proprio crontab, qui di seguito. L'editor di testo usato è quello specificato dalle variabili d'ambiente VISUAL o EDITOR, controllate in questo ordine. È importante usare questo comando, in alternativa a modificare a manina il file, perché previene gli errori più banali controllando la correttezza sintattica.

$ crontab -e

Per modificare il crontab di un altro utente si usa, come root:

$ sudo crontab -u qualcun_altro -e

Per il crontab dell'utente root semplicemente:

$ sudo crontab -e