Comment envoyer, à partir d’un Rasberry Pi, un fichier txt toutes les 20 minutes à un serveur distant ? La réponse passe par une connexion FTP et un cronjob, ou tâche planifiée.
Mes objectifs
Sur un Raspberry Pi, j’ai créé un script Shell qui relève la température, la date et l’heure, le nom du Pi et les écrit dans un fichier txt avec la chaîne de caractère définie dans la commande. Ce script, est décrit dans l’article « Raspberry Pi : Mesurer la température avec un capteur DS18B20. Le fichier texte créé s’appelle [hostname]-status.txt.
Maintenant je veux envoyer ce fichier texte à un serveur distant, en FTP.
Et je veux que cet envoi soit réalisé automatiquement toutes les 20 minutes.
Envoyer un fichier à un serveur distant en FTP
Pour connecter un Pi comme client à un serveur, il faut lui installer une application.
Pour installer le package FTP (j’ai choisi celui qui paraissait le plus léger) :
apt-get install ftp
Maintenant, je peux me connecter à un serveur distant.
Je crée le script send-status.sh, avec droits 744 (exécutable) :
#!/bin/bash
printenv
# check my Hostname variable
ThisHost=$(hostname)
date=$(date)
# There should be no ECHO in a CRON job
echo $ThisHost
# $1 is the variable appended to the file when executed
# example : ./send-status.sh essai would put "essai" in $1
# local file to send
FILE=$ThisHost"-status.txt"
# local directory to pick the file for upload
REPERTOIRE="/home/jf/temp/"
echo $REPERTOIRE$FILE
# https://www.raspberrypi.org/forums/viewtopic.php?t=68541&p=500070
# https://www.raspberrypi.org/forums/viewtopic.php?f=91&t=51222
#credentials to access the remote directory
USERNAME="USERNAME"
PASSWORD="PWORD"
SERVER="URL-DU-SERVEUR"
# remote server directory to upload backup
BACKUPDIR="/My-pi/"
echo "Attempting ftp upload~, ..."
cd $REPERTOIRE
ftp -in $SERVER <<EOMYF
user $USERNAME $PASSWORD
pwd
cd $BACKUPDIR
put $FILE
bye
EOMYF
Lorsque je l’éxécute en ligne de commande (), le serveur reçoit bien le fichier texte.
Le Pi affiche un message de succès (mais si) :
Attempting ftp upload~, ...
257 "/" is the current directory
Donc cette opération est correctement réalisée par la ligne de commande.
Réaliser cette action automatiquement (tâche planifiée)
Nous avons déjà essayé le script à la main avec
cd /home/jf/exec
./send-status.sh OK
Et ça fonctionnait. Maintenant, il faut définir l’environnement d’abord, puis indiquer la commande à exécuter et sa fréquence.
Planifier l’exécution du script
Sur le pi, éditer /etc/crontab avec crontab –e :
Y ajouter à la fin (utiliser SHIFT INS pour coller) :
Dans un article précédent (Cron Job sur un hébergement mutualisé OVH), j’ai expliqué comment exécuter un script périodiquement, et automatiquement, dans un hébergement mutualisé OVH pro. Nous allons voir comment le faire sur un serveur mutualisé Plesk (Offre VPS Classic d’OVH).
J’utilise le fichier /domicile.mon-domaine.com/cron-suivi-pi.php. Son contenu est semblable à celui de l’article précédent. Ce fichier m’envoie un mail lorsqu’il s’exécute et que certaines conditions sont réunies.
Je l’ai vérifié en plaçant http://domicile.mon-domaine.com/cron-suivi-pi.php dans un navigateur. Il n’y a pas d’erreurs et les « echo » s’affichent sur la page.
Nota : on a intérêt à activer l’affichage des erreurs : en étant administrateur, aller dans paramètres PHP et mettre display_errors sur « on ».
Réglage des tâches planifiées
Dans l’interface Plesk, Sites Web & Domaines > tâches planifiées, on peut régler le fuseau horaire des taches planifiées :
Plesk, tâche planifiée : régler le fuseau horaire
Planifier la tache
C’est incroyablement simple, ça se passe de commentaires !
La seule chose qui peut être compliquée, c’est si on veut planifier « cron style », comme ici. Pour définir l’heure, on peut alors s’aider de ce générateur de commande cron ou cet autre générateur.
Plesk, régler une tâche planifiée (cron)
Vérifier
Dans la liste des tâches planifiées, cliquer sur « exécuter maintenant ».
Plesk, exécuter maintenant un cron
Si tout s’est bien passé : un message sur fond vert dans Plesk et pas de mail d’erreur reçu et le mail prévu s’est envoyé (si les conditions sont réunies).
Et voilà, encore une nouvelle manip dans Plesk qui est maîtrisée ! Pour tout savoir sur la prise en main de Plesk, lire les autres articles de cette série Démarrer avec un hébergement VPS Plesk d’OVH.
Dans le premier article de cette série, Caméra de surveillance et Raspberry Pi, nous avons lu le flux d’une caméra IP dans un Raspberry Pi. Dans cet article, nous allons voir comment supprimer automatiquement les fichiers, vidéos ou images, sauvegardés au fil du temps.
Il y a urgence !
J’ai installé motion sur mon Raspberry Pi le 22 juin. On est le 1er juillet et le répertoire de stockage des images et vidéos représente déjà plus de 1 Go et 40 000 fichiers.
Il faut donc que j’automatise la suppression d’images de plus de deux jours (cet article) et aussi que je règle mieux motion pour qu’il ne stocke que les images et vidéos de véritables mouvements détectés (le prochain article de cette série, Caméra de surveillance et Raspberry Pi.
Supprimer des fichiers manuellement
Dans les FAQ de motion, ici, on voit comment déclencher la suppression de fichiers en fonction de leur localisation, leur extension et leur date. Ainsi, la commande suivante trouve et supprime tous les fichiers en jpg vieux de plus de 1 jour :
Mais on ne veut pas aller taper cette commande tous les jours dans notre Pi. Il faut donc planifier la commande.
Crontab pour planifier des actions
Comme indiqué dans Wikipedia, « cron est un programme qui permet aux utilisateurs des systèmes Unix d’exécuter automatiquement des scripts, des commandes ou des logiciels à une date et une heure spécifiées à l’avance, ou selon un cycle défini à l’avance. […] crontab est le nom du programme qui permet d’éditer des tables de configuration du programme cron. Ces tables spécifient les tâches à exécuter et leur horaire d’exécution avec éventuellement une périodicité. »
Ce qui suit provient aussi des FAQ de motion, ici :
créer un script bash (/home/jf/exec/camera-delete-cron.sh) comme celui-ci (note du 25/01/2018, j’ai corrigé et ça fonctionne correctement maintenant) :
#!/bin/bash
# /home/jf/motion/camera–delete–cron.sh
# connaître les variables d'environnement du cron, pour deboguer
# printenv ;
# me dit que HOME et PWD = /home/jf
# efface les fichiers avi et jpg de plus de 14 jours
find /home/jf/motion/foscam/ -name '*.avi' -type f -mtime +14 -exec rm {} \;
find /home/jf/motion/foscam/ -name '*.jpg' -type f -mtime +14 -exec rm {} \;
l’ajouter au cron (voir les instructions pour le Raspberry Pi sur le site officiel du Pi).
la ligne de commande dans crontab
Le schéma ci-dessous traduit les instructions du site officiel du Pi.
# * * * * * commande à exécuter
# ┬ ┬ ┬ ┬ ┬
# │ │ │ │ │
# │ │ │ │ │
# │ │ │ │ └───── jour de la semaine (0 - 7) (dimanche est 0 ou 7, lundi est 1)
# │ │ │ └────────── mois (1 - 12)
# │ │ └─────────────── jour du mois (1 - 31)
# │ └──────────────────── heure (0 - 23)
# └───────────────────────── minute (0 - 59)
# └───────────────────────── /xx = toutes les xx minutes
J’ai créé le script bash ci-dessus et l’ai appelé camera-delete-cron.sh . Je lui ai donné les droits 764. Evidemment, ses fins de ligne doivent être au format unix.
Je vérifie qu’il fonctionne avec les commandes suivantes :
cd /home/jf/exec
./camera-delete-cron.sh
Je veux l’exécuter tous les jours à 1h00. J’ai utilisé le générateur de commande cron de ce site pour définir ma commande cron. En principe j’écrirai donc :
Avant j’ai indiqué l’environnement d’exécution des commandes. Voir ci-dessous si vous devez adapter. Attention, il doit y avoir une ligne vide à la fin du crontab…
On édite crontab en tapant crontab -e dans la console. On y ajoute la ligne suivante (SHIFT + INSER pour coller). Attention, il doit obligatoirement y avoir une ligne vide à la fin du contenu de crontab.
Noter le « bash » devant le fichier à exécuter.
Le cron ne s’exécutera automatiquement qu’après un redémarrage du Pi. Donc
Déboguer le cron si nécessaire
Ce n’est pas simple de déboguer si un cron ne s’éxécute pas correctement. Le plus probable est que l’environnement d’éxécution du cron n’est pas le même que celui de la ligne de commande.
Un cron job se déclenche dans un environnement différent de celui d’un lancement manuel !
Dans le script on peut ajouter printenv, qui affiche toutes les variables d’environnement. Un fichier log recueillerales données issues du cron job si la ligne est (ici exécution toutes les 10 minutes d’un script camera-test.sh et envoi des résultats dans un répertoire cron.log) :
Dans un projet personnel, j’ai eu besoin de lancer un script régulièrement sur mon hébergement mutualisé OVH. Et j’ai constaté que ce n’est pas simple ! Je décris ici un script test, qui fonctionne après de multiples essais.
Le principe
Je veux que OVH exécute un script PHP à fréquence régulière. Le script PHP présenté ici réalise différentes activités qui permettent de vérifier que mes réglages sont bons. Il s’agit en effet de répondre aux questions suivantes :
comment faire pour que OVH exécute régulièrement un script (PHP ici) ?
Si le script doit accéder à d’autres fichiers, comment lui « dire » où les trouver ?
Si le script doit envoyer un mail, quelles sont les spécifications pour que ça fonctionne ?
Comment faire pour deboguer et afficher ce qui se passe durant le script « croné » ?
Ecriture du script PHP
Le fichier « cron-test.php »final, qui fonctionne, contient les éléments suivants :
La partie html permet de visualiser (et lancer) le script à partir d’internet, en tapant l’adresse http://mon-site.com/cron-test.php, comme ci-dessous.
Ce qui est réellement important, c’est le code php.
Pour que OVH puisse exécuter ce script en cron
Il vaut mieux (c’est optionnel pour du PHP), indiquer en toute première ligne du fichier comment il doit se décoder :
#!/usr/local/bin/php
Mais surtout, il faut comprendre que l’environnement dans lequel s’exécute un cron n’est pas celui dans lequel on exécute à la main (ou dans le navigateur comme ci-dessus). Le script ne sait pas où il est et il faut lui donner l’information ! On définit ainsi une variable ROOT avec la fonction define() puis on l’indique à chaque fois qu’il faut aller chercher un fichier, ici lorsqu’on veut utiliser un autre fichier pour définir les fonctions utilisées ou pour indiquer le chemin vers un fichier cron-pi.log que l’on veut ouvrir pour y ajouter du texte à la fin.
Aller sur l’espace client OVH et sélectionner l’hébergement du nom de domaine correspondant. Cliquer sur l’onglet Cron puis choisir « ajouter une planification ».
Dans mon cas, le script est placé dans le répertoire pi-suivi/ .
Après avoir cliqué sur suivant, il faut que je choisisses la fréquence de réalisation du script. Ici j’ai utilisé le mode simple et je n’ai rien modifié : je veux une exécution toutes les heures. Noter qu’on ne peut pas régler les minutes, même en mode expert. Sur un hébergement mutualisé OVH, ce n’est pas possible.
Après avoir cliqué sur « suivant », voici la synthèse de ce que j’ai choisi. Notez le « ? » pour les minutes. C’est OVH qui va en décider la valeur.
Je valide et j’attends 1 à 2 minutes. Je rafraichis la page de mon espace client OVH et la tâche Cron apparaît. J’avais déjà créé une autre tâche Cron. On voit que OVH a décidé qu’elle s’exécuterait à chaque fois qu’il est xh51. La deuxième tâche sera elle réalisée à chaque fois qu’il est xh40.
J’attends qu’il soit xh40 et quelques, puis je vois que mon script s’est exécuté : j’ai reçu le mail généré par la fonction
Déboguage
Pour en arriver là, j’ai bien galéré et j’ai dû apprendre comment déboguer sur OVH.
En particulier, j’ai finalement trouvé où se trouvent les logs des hébergements mutualisés ! Il suffit de taper « https://logs.ovh.net/mon-site.com/ puis d’indiquer son identifiant OVH et son mot de passe (ceux qu’on utilise pour accéder à l’espace client). Par exemple, mes logs sont sur https://logs.ovh.net/parcours-performance.com/.
On trouve alors une ligne contenant « Cliquez ici pour voir les logs bruts en temps réel : web – ftp – error – cgi – out – ssh – cron ». On clique sur « cron » et on accède au dernier log des cron.
Les logs commencent par, et se terminent par ce qui suit. Entre les deux lignes, il y a le HTML. Ici j’ai remplacé le chemin vers mon répertoire par *** pour des raisons de sécurité.
Un cron s’est exécuté correctement s’il se termine par exitcode:0.
Mais évidemment, du point de vue du serveur un cron se termine correctement s’il n’y a pas d’erreur. De mon point de vue, il est terminé correctement s’il a réalisé ce que j’attendais….
Ecrire dans un fichier permet de vérifier ce qui se passe durant l’exécution du code. Ainsi j’ai défini $line1 puis je l’écris dans le fichier log défini. Ca me permet de savoir dans quel répertoire se déroule le travail.
Mais un des rôles les plus importants d’un tel fichier log est de nous dire si les choses se sont bien passées :
exemple 1 : écrire dans un log le résultat d’une interaction
Dans le script ci-dessus, j’appelle une fonction, al_send_email, par la commande :
Cette fonction (non présentée ici ) gènère un mail à destination de $to, avec $subject comme objet et $message dans le corps du mail. C’est bien beau de lancer une fonction. Mais ce qui est essentiel, c’est de savoir si le mail a effectivement été expédié.
Et bien $send_mail contient cette information maintenant que la fonction a été exécutée. En effet la fonction contient la ligne ‘return $result ; » et $result est réglé à » ### » . $send_Mail . » – Erreur envoi mail <br> \n » si le serveur de messagerie n’a pas répondu « true » lors de l’envoi. Je peux donc indiquer dans mon log si tout s’est bien passé.
exemple 2 : écrire dans un log le contenu d’un tableau (array)
Un autre exemple où la constitution d’un log est essentielle pour déboguer un script, c’est lorsqu’on manipule des tableaux (array).
Dans un autre script php j’utilise cette fonctionnalité en définissant $line1 comme contenant toutes les valeurs d’un array $list_pi :
$line1 = var_export( $list_pi, true ) ;
Le log correspondant va ainsi contenir le texte suivant pour $line1 :
array (
0 => 'val1',
1 => 'val2',
2 => 'val3',
)
D’un coup d’oeil dans le log, je vois si le script tel que réalisé dans l’environnement cron s’est déroulé comme prévu.
Maintenant, il ne reste plus qu’à trouver d’autres actions à réaliser fréquemment. Il peut s’agir d’une sauvegarde de la base de données ou d’autres constructions plus sophistiquées.
Commentaires récents