Nella precedente lezione abbiamo illustrato il funzionamento di at, un comando che consente di eseguire un task specifico pianificando, da linea di comando, il momento preciso di esecuzione oppure l’intervallo di tempo prima che il task venga eseguito. Ciò va benissimo per i task che intendiamo eseguire una sola volta. Per quelli che intendiamo ripetere più volte a intervalli di tempo prefissati abbiamo, invece, a disposizione uno strumento che consente una maggiore flessibilità di utilizzo. Cron può essere adoperato a livello utente (root o normal user) oppure a livello di sistema ma sempre operando su alcuni file di configurazione. Cron è un demone che controlla, a intervalli di un minuto, una serie di file chiamati crontab files. Un file crontab contiene informazioni che istruiscono il demone sui processi da avviare, quando avviarli ed eventualmente quale utenza considerare proprietaria dei processi lanciati.
Cron: livello sistema
L’uso di cron a livello di sistema risulta molto intuitivo poiché semplicemente si appoggerà ad alcuni script che automatizzano le operazioni da effettuare. Questi andranno inseriti, con nome privo di estensione, nelle directory:
- /etc/cron.hourly
- /etc/cron.daily
- /etc/cron.weekly
- /etc/cron.monthly
Gli stessi saranno eseguiti, rispettivamente, ogni ora, ogni giorno, settimanalmente e mensilmente. Andiamo a visionare un esempio.
fprincipe@html52:~$ more /etc/cron.hourly/task
#!/bin/bash
date +"cron.hourly - $HOSTNAME %d/%m/%y %H:%M">>/root/current
Non entriamo nello specifico delle opzioni di date, potrete approfondirle autonomamente se lo riterrete opportuno. Vi basti sapere che il comando inserito genera, ogni volta, una riga che inizia con i caratteri sino al “-“, quindi a, seguire, l’orario corretto. Questo output viene accodato al file /root/current.
Cron: livello utente
Adesso cominceremo a intravedere le opzioni offerte da cron poiché introdurremo una maggiore complessità. Per comrendere al meglio l’argomento ci confronteremo con un file crontab vero e proprio.
fprincipe@html52:~$ more /etc/crontab
# /etc/crontab: system-wide crontab
[...]
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# m h dom mon dow user command
[...]
10 * * * * fprincipe date +"crontab-general:10 - $HOSTNAME \%d/\%m/\%y \%H:\%M">>~/current
00 * * * * fprincipe date +"crontab-general:00 - $HOSTNAME \%d/\%m/\%y \%H:\%M">>~/current
Abbiamo aperto il file crontab generale di sistema. Osservate le ultime due righe della schermata subito sopra, ogni rigo rappresenta un comando da eseguire secondo le specifiche. I comandi in questione saranno lanciati come se fossero eseguiti dall’utente fprincipe e aggiungeranno nel file current della sua home directory righe che iniziano con il testo crontab-general. Le entry crontab sono costituite da sette campi distinti che informano cron su cosa intendiamo far lanciare al demone. Andiamo a vedere con una tabella cosa rappresentano questi campi. Prima, però, occorre sapere che “*” indica “qualsiasi”.
Primo Campo | Minuti. Nella prima riga dell’esempio chiediamo che il comando venga eseguito al decimo minuto di ogni ora. La seconda riga chiede la stessa cosa ma esattamente allo scoccare di ogni ora. |
Secondo Campo | Orario dell’esecuzione. |
Terzo Campo | Giorno dell’esecuzione. |
Quarto Campo | Mese dell’esecuzione. |
Quinto Campo | Giorno della settimana (da domenica “0” a sabato “6”) in cui eseguire il comando. |
Sesto Campo | Utente a cui assegnare il processo. |
Settimo Campo | Comando da eseguire. |
Ragionando sulla modularità di un simile approccio possiamo prendere atto delle grandi potenzialità che offre. La cosa appare ancora più evidente se consideriamo anche altre opportunità di parametrizzazione. Ad esempio, un valore “*” seguito da “/numero” può essere tradotto come ogni numero unità di tempo. Mentre con l’uso del “-” fra due valori descriviamo l’intervallo compreso fra gli stessi. A esempio se i primi due campi di un rigo crontab fossero “*/3 8-12” chiederemmo di eseguire il comando ogni 3 minuti ma solo dalle ore 8 alle 12. I primi cinque campi possono essere anche sostituiti da stringhe riassuntive:
@hourly | Lancia il comando ogni ora. |
@daily e @midnight | Lancia il comando ogni giorno. |
@weekly | Lancia il comando una volta a settimana. |
@monthly | Lancia il comando una volta al mese. |
@annually e @yearly | Lancia il comando una volta l’anno. |
@reboot | Lancia il comando una volta a ogni reboot |
Abbiamo appena presentato un approccio di cron operato a livello di sistema ma volto ad assegnare utenti specifici al lancio dei comandi descritti nell'ultimo campo di ogni riga. E' possibile lasciare ai singoli utenti la possibilità di creare autonomamente proprie specifiche crontab. Per ragioni di praticità presentiamo ora diverse schermate in successione, scorretele sino al testo a seguire poiché saranno illustrate una per una.
GNU nano 2.9.3 /tmp/crontab.lIlo7k/crontab Modified
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
[...]
^G Get Help ^O Write Out ^W Where Is ^K Cut Text ^J Justify ^C Cur Pos
^X Exit ^R Read File ^\ Replace ^U Uncut Text^T To Spell ^_ Go To Line
crontab: installing new crontab
"/tmp/crontab.lIlo7k/crontab":24: bad minute
errors in crontab file, can't install.
Do you want to retry the same edit? (y/n)
crontab: installing new crontab
Per creare un file crontab a livello utente è opportuno invocare l'editor tramite il comando "crontab -e". Se per l'utente in questione è la prima volta che lo facciamo verrà proposta una scelta fra gli editor disponibili e potremo farne partire uno digitando il numero corrispondente a quello che preferiamo. Nella prima schermata della sequenza subito sopra vediamo, a esempio, in anzione l'editor nano. Quando salviamo viene generato un file temporaneo che sarà passato attraverso un controllo di coerenza. Nella seconda schermata della sequenza vediamo il messaggio di errore a schermo quando il file crontab contiene degli errori. Anche operando da semplice user le righe andranno formattate come nell'esempio del file /etc/crontab ma i campi saranno uno in meno poichè, per ovvie ragioni, l'utente va omesso. Se tutto è andato a dovere vedrete l'ultima schermata della sequenza. Per listare le entry crontab di un utente è possibile utilizzare il comando "crontab -l".
Precludere cron
Ovviamente l'Amministratore di Sistema potrà ritenere opportuno impedire a uno o più utenti di creare propri crontab. E' possibile far ciò inserendo nel file cron.deny un username per riga. Così facendo l'utente, al tentativo di creare un proprio crontab, vedrà una schermata simile a quella subito a seguire.
You (fprincipe) are not allowed to use this program (crontab)
See crontab(1) for more information
Il file cron.deny potrebbe avere percorso variabile in funzione delle distrubuzioni. Il modo più semplice per comprendere dove vada posizionato è usare il comando man crontab e consultare l'informazione relativa. Con funzionamento opposto e simmetrico ma del tutto similare potremo creare un file cron.allow che, se presente, elencherà, uno per riga, gli utenti che possono creare propri crontab. Il file cron.allow ha la precedenza sul file cron.deny qualora un username esista in entrambi.
Risultati
Se qualcosa è andato storo potrà essere utile sapere che molti messaggi di errore di cron sono presenti nel file /var/log/syslog. Adesso siamo pronti per vedere il risultato dei vari crontab che abbiamo "seminato" in questa lezione.
fprincipe@html52:~$ more current
crontab-general:00 - 29/12/18 13:00
crontab-general:10 - 29/12/18 13:10
crontab-general:00 - 29/12/18 14:00
crontab-general:10 - 29/12/18 14:10
crontab-general:00 - 29/12/18 15:00
fprincipe@html52:~$ sudo more /root/current
cron.hourly - html52 29/12/18 13:17
cron.hourly - html52 29/12/18 14:17