Abarone.it Logo

Programmare l'esecuzione di script

Parte 1 - Introduzione a cron

Una funzione importante all'interno del nostro Raspberry Pi, è la possibilità di poter eseguire determinati script a determinati orari pre-stabiliti. Un esempio è dato senza ombra di dubbio dalla possibilità di attivare la funzionalità di videosorveglianza durante la notte.

Cron è un tool presente su tutti i sistemi Unix che ci consente di schedulare task secondo le nostre esigenze, ovvero ci permette di eseguire comandi o script che si avviano periodicamente e a intervalli fissati.

Il comando cronotab viene utilizzato per modificare l'elenco di operazioni pianificate, ed è costruito in funzione dell'utente, infatti ogni utente ( compreso root) ha il proprio crontab

Modifica Crontab
Per modificare il crontab, eseguire il comando

  1. -e contab

La prima volta che viene eseguito crontab ci verrà richiesto di scegliere un editor, scegliamo senza timori l'editor nano cliccando Invio.

Il layout del crontab è costituito da 6 componenti:
- minuto
- ora
- giorno del mese
- mese dell'anno
- giorno della settimana
- il comando da eseguire

Vediamo un esempio

  1. # Mh dom comando mon dow
  2. .---------------- [m]inute: minuto (0 - 59)
  3. | .------------- [h]our: ora (0 - 23)
  4. | | .---------- [d]ay [o]f [m]onth: giorno del mese (1 - 31)
  5. | | | .------- [mon]th: mese (1 - 12) OPPURE jan,feb,mar,apr...
  6. | | | | .---- [d]ay [o]f [w]eek: giorno della settimana (0 - 6) (domenica=0 o 7) OPPURE sun,mon,tue,wed,thu,fri,sat
  7. | | | | |
  8. * * * * * Comando da eseguire

Per esempio:

  1. 0 0 * * * /home/pi/backup.sh

Questo comando esegue lo backup.sh ogni giorno a mezzanotte

PS. per abilitare il log del cron ( su raspbian di default è disabilitato) bisogna eseguire:

  1. sudo nano /etc/rsyslog.conf e togliere il commento da </p>
  2. <h1>cron* /var/log/cron quindi riavviamo</h1>
  3. <p>/etc/init.d/rsyslog restart

Il risultato del cron sarà in :
  1. /var/log/syslog


Problematiche

Vediamo quali problematiche possono sorgere durante l'esecuzione degli script e in particolare andiamo ad analizzare un paio di problematiche che possono andare in conflitto e quindi portare alla cattiva riuscita dell'esecuzione automatica degli script.

Innanzitutto va ricordato che affinché uno script possa essere eseguito dobbiamo rendere il file eseguibile, per fare questo eseguiamo

  1. sudo chmod +x nomefile.sh

o in alternativa

  1. sudo chmod 755 nomefile.sh

Questa procedura può essere saltata se lo script è eseguito dall'utente root.

Quindi per rendere lo script eseguibile in automatico andiamo da terminale eseguiamo:

  1. sudo nano /etc/rc.local

Quindi dopo le linee commentate andiamo a inserire:

  1. sudo /home/pi/projects/nomefile.sh &

Sudo indica che vogliamo che lo script venga eseguito con i privileggi di amministratore, e & indica che vogliamo che venga eseguito in background, se non ci interessano possiamo anche eliminarle. Andiamo ora a vedere un'altra procedura per eseguire automaticamente uno script.


Seconda Procedura

La seconda procedura ( che io preferisco alla prima ) è quella di creare uno script e richiamarlo in automatico ( dal crontab ) . Per far questo eseguiamo:

  1. mkdir ./bin
  2. cd ./bin

Quindi creiamo uno script prova.sh scrivendo da shell sudo nnao prova.sh , quindi previamo invio e andiamo a inserire nel file il codice:

  1. </p>
  2. <h1>!/bin/bash</h1>
  3. <h1>Script to start our application</h1>
  4. <p>echo "Doing autorun script..."

Il file di prova è pronto, per eseguirlo rendiamo il file eseguile scrivendo chmod +x /home/pi/bin/prova.sh

Siamo pronti. Per eseguire il file basterà eseguire il comando da shell:

  1. /home/pi/bin/prova.sh


Soluzione Presa dal Web

La domanda era se si volesse eseguire lo script ogni primo mercoledi di ogni mese, alle ore 12 ?
La questione non è banale.

Non essendoci in cron la possibilità diretta di impostare una regola di questo tipo, una possibile soluzione è quella di inserire nello script da eseguire una valutazione sulla giornata attuale. La verifica della condizione se il giorno in corso è Mercoledì, con conseguente uscita diretta se è un qualsiasi altro giorno. Soluzione poco elegante e di difficile interpretazione da parte di altri in caso di manutenzione. Decido di cercare qualcosa di diverso.

In prima approssimazione il comando che mi viene spontaneo creare è il seguente

  1. 0 12 1-7 * 3 job.sh
  2. 0 = minuto 0
  3. 12 = ora 12
  4. 1-7 = giorni del mese da 1 a 7, considerando che il <em>primo</em> Mercoledì deve essere in questo intervallo
  5. * = tutti i mesi
  6. 3 = giorno della settimana Mercoledì
  7. job.sh = script da eseguire

Apparentemente ha una sua ragion d’essere, ma c’è qualcosa che non va. Infatti l’impostazione 1-7 non è alternativa all’indicazione del giorno 3 (Mercoledì). In altre parole causa l’esecuzione in ognuno di quei giorni e non solo il primo Mercoledì.

La soluzione corretta (perlomeno una che mi piace) è questa

  1. 0 12 * * 3 [ <code>date +\%d</code> -le 7 ] && job.sh
  2. 0 = minuto 0
  3. 12 = ora 12
  4. * = qualunque giorno del mese
  5. * = tutti i mesi
  6. 3 = giorno della settimana Mercoledì
  7. [ <code>date +\%d</code> -le 7 ] &&
  8. job.sh = script da eseguire

La magia avviene nella condizione [ date +%d -le 7 ] && della shell bash che restituisce un codice d’uscita basato sul fatto che la condizione sia vera o falsa. Se la condizione è vera si avrà l’esecuzione dello script, viceversa no. Inserendolo in crontab è necessario delimitare con backslash () il selettore %.

Ciò che stiamo facendo è una chiamata alla shell che valuta date +%d, ovvero esegue il comando date con l’attributo +%d, che restituisce il valore numerico di oggi, ad esempio 02.

Il resto della condizione -le 7 verifica se quel valore, il numero del giorno attuale, è minore o uguale a 7. Se è così, allora il giorno è nella prima settimana del mese, quindi viene restituito 1/vero, altrimenti il codice restituito è 0/falso e l’esecuzione viene fermata.

Quindi il comando viene eseguito da cron ogni settimana, di mercoledì, ma procede con il lancio dello script solo quando viene eseguito nei primi 7 giorni del mese.


Soluzione dal web per script motion

Sul computer che uso per il controllo ho creato tre files eseguibili (ovviamente la directory "/home/$USER/bin" e` nel path di ricerca degli eseguibili).
"/home/$USER/bin/RaspberryPi-motion.sh"
L'avvio di motion-mmal

  1. #!/bin/bash
  2. # Stop motion
  3. /home/$USER/bin/RaspberryPi-motion-stop.sh
  4. # Start motion
  5. ssh pi@<NomeDelRaspberriPi o IP> /home/pi/motion-mmalcam/motion -n -c /home/pi/motion-mmalcam/motion-mmalcam.conf &

"/home/$USER/bin/RaspberryPi-motion-stop.sh"

Lo stop di motion-mmal

  1. #!/bin/bash
  2. # Stop motion
  3. ssh pi@<NomeDelRaspberriPi o IP> /home/pi/motion-mmalcam/motion-kill.sh
  4. sleep 2

"/home/$USER/bin/RaspberryPi-stream.sh"
Avvia lo streaming fra i due pc, ed il client video sul pc locale

  1. #!/bin/bash
  2. # Stop motion
  3. /home/$USER/bin/RaspberryPi-motion-stop.sh
  4. # Start camera e streaming (in ascolto, switch -l di 'nc')
  5. ssh pi@<NomeDelRaspberriPi o IP> "raspivid -w 640 -h 360 -fps 12 -rot 180 -t 0 -o - | nc -l 10301" &
  6. sleep 2
  7. # Start local player
  8. nc <NomeDelRaspberriPi o IP> 10301 | mplayer -fps 30 -demuxer h264es -

barone.antonio@libero.it