traitement automatique d'un fichier
Introduction
Le script de shell proposé, destiné à Linux et utilisable en tant que spouleur, surveille un répertoire donné (de spool). Lorsqu'il y détecte création d'un fichier il lance automagiquement un traitement.
Il emploie le service « inotify » donc ne polle pas.
Installation
Installer les utilitaires « inotifywait » (sous Debian: paquetage « inotify-tools » ) et « logger » (Debian: « bsdutils »).
Éditer le script:
- la variable « SPOOLDIR » doit contenir le nom d'un répertoire, existant et vide, où tout fichier à traiter sera déposé
- la variable ARCHIVEDIR doit contenir le nom d'un répertoire existant où le script déplacera tout fichier traité
- la section « traitement » doit effectuer les traitements (la variable TMPFILNAM contient le nom du fichier à traiter). Dans le script proposé le traitement consiste à révéler à bogofilter et à SpamAssassin qu'un fichier recelant un courriel est du ham. Note: idéalement les logiciels impliqués communiquent eux aussi via syslog
Invoquer le script via la ligne de commande, en avant-plan, puis le tester et mettre au point en plaçant (créant, copiant ou déplaçant) un fichier dans le répertoire SPOOLDIR. Le script confie ses messages à syslog, donc surveiller les logs.
Lorsque tout fonctionne, paramétrer de sorte qu'il soit automatiquement invoqué sous le compte utilisateur adéquat, par exemple en éditant /etc/rc.local afin qu'il contienne:
su - nat -c ~nat/outils/ham &
remplacer 'nat' par le nom de connexion associé au compte, et '~nat/outils/ham' par le chemin complet du fichier script. On peut préférer le faire via init ou bien cron (/etc/crontab , date spéciale "@reboot", voir « man 5 crontab »).
Utilisation
Placer tout fichier à traiter dans le répertoire SPOOLDIR. Son nom importe peu.
Pour faciliter cela on peut établir un lien symbolique, par exemple ainsi:
cd # retour au répertoire HOME mkdir -p tmp/ham_spool # création du SPOOLDIR ln -s tmp/ham_spool .ham # création d'un lien
Il suffira ensuite, pour requérir traitement d'un fichier, de le copier par exemple dans « ~/.ham/m », ce qui est moins long à saisir que « ~/tmp/ham_spool/l ».
Limitations
Aucun verrouillage, donc plusieurs instances (sens 2) de ce script peuvent simultanément fonctionner. Si c'est inadéquat il sera facile d'y remédier.
Les fichiers présents dans le SPOOLDIR lors du démarrage du script ne sont pas traités. C'est délibéré. Pour déclencher leur traitement, lancer le script puis les toucher.
Chaque fichier est individuellement pris en charge, il n'est pas possible de traiter plusieurs fichiers à la fois.
Aucun filtrage ou sélection n'est assuré, qui offrirait par exemple moyen de lancer un traitement dépendant du nom du fichier ou de son heure de création.
Script
#!/bin/bash #set -o errexit # Nom de ce script, tel qu'il apparaîtra dans les logs MYNAME=ham # Nom du répertoire où ce script trouvera les fichiers à traiter SPOOLDIR=~/tmp/ham_spool # Nom du répertoire où ce script déplacera les fichiers après traitement ARCHIVEDIR=~/tmp/ham # syslog facility SYSLOGFAC=daemon ## No configuration after this line MYVERSION=0.12 MYLOGNAME="$MYNAME"_"$MYVERSION" logger -i -p "$SYSLOGFAC".info -t "$MYLOGNAME" -- Starting [ ! -d "$ARCHIVEDIR" ] && { logger -i -p "$SYSLOGFAC".err -t "$MYLOGNAME" -- No ARCHIVEDIR directory found, please create it; exit 4; } [ ! -d "$SPOOLDIR" ] && { logger -i -p "$SYSLOGFAC".err -t "$MYLOGNAME" -- No SPOOLDIR directory found, please create it; exit 5; } cd "$SPOOLDIR" || { logger -i -p "$SYSLOGFAC".err -t "$MYLOGNAME" -- "Cannot reach SPOOLDIR"; exit 6; } while TMPPREFILNAM="$SPOOLDIR"/$(inotifywait -e close_write --format="%f" -q ./) ; do logger -i -p "$SYSLOGFAC".info -t "$MYLOGNAME" -- Despooling "$TMPPREFILNAM" TMPFILNAM=`mktemp --tmpdir="$SPOOLDIR" ham_tmpXXXXXX` if [ ! -f "$TMPFILNAM" ] ; then logger -i -p "$SYSLOGFAC".err -t "$MYLOGNAME" -- Cannot create tmp file "$TMPFILNAM" exit 7 fi mv "$TMPPREFILNAM" "$TMPFILNAM" || { logger -i -p "$SYSLOGFAC".err -t "$MYLOGNAME" -- mv failed "$TMPFILNAM"; exit 8; } [ ! -s "$TMPFILNAM" ] && logger -i -p "$SYSLOGFAC".notice -t "$MYLOGNAME" -- Warning: "$TMPFILNAM" file is empty # [ ! -f "$TMPFILNAM" ] && logger -i -p "$SYSLOGFAC".notice -t "$MYLOGNAME" -- Warning: "$TMPFILNAM" is not a regular file [ ! -r "$TMPFILNAM" ] && logger -i -p "$SYSLOGFAC".notice -t "$MYLOGNAME" -- Warning: "$TMPFILNAM" file cannot be read # traitement bogofilter -S -I "$TMPFILNAM" [ "$?" -ne 0 ] && logger -i -p "$SYSLOGFAC".err -t "$MYLOGNAME" -- Warning: bogo1 failed sa-learn --forget "$TMPFILNAM" [ "$?" -ne 0 ] && logger -i -p "$SYSLOGFAC".err -t "$MYLOGNAME" -- Warning: sa-learn1 failed bogofilter -n -I "$TMPFILNAM" [ "$?" -ne 0 ] && logger -i -p "$SYSLOGFAC".err -t "$MYLOGNAME" -- Warning: bogo2 failed sa-learn --ham "$TMPFILNAM" [ "$?" -ne 0 ] && logger -i -p "$SYSLOGFAC".err -t "$MYLOGNAME" -- Warning: sa-learn2 failed # déplacement (archivage) mv --backup=numbered "$TMPFILNAM" "$ARCHIVEDIR" || logger -i -p "$SYSLOGFAC".err -t "$MYLOGNAME" -- Cannot mv "$TMPFILNAM" done