Pense-bête in the Shell
Par Dimitri Robert, mercredi 26 octobre 2005 à 14:02 :: Programmation :: #33 :: rss
Il y a un petit moment de cela, j'avais écrit un script de pense-bête dans Linux Pratique. J'ai récemment ressorti ce script qui me sert beaucoup. J'ai aussi épousseté (légèrement) l'article explicatif qui accompagnait.
Le but
Si vous avez tendance à tapisser les bords de votre écran avec des petits papiers (généralement jaunes) pour vous rappeler tout ce que vous avez à faire, ou que vous faites confiance à votre mémoire, parfois vacillante, voici peut-être une solution. Loin de l'utilisation d'un logiciel de type agenda (comme « Mozilla Calendar ») nous allons vous proposer un petit script qui vous affichera une simple boîte de dialogue au moment où vous aurez choisi de vous faire prévenir.
Les ingrédients
- Xdialog, outil permettant l'affichage de boîtes de dialogues diverses et variées de manière très simple
at, planificateur de tâches, à comparer aveccron- Bash, le shell
Les principes
L'idée est toute simple : demander à notre système préféré de nous afficher un message à un moment précis pour nous rappeler, par exemple, un rendez-vous important, une émission de radio à ne pas oublier, sortir le chien, etc. Ce message sera affiché dans une boîte de dialogue grâce à Xdialog.
Pour déclencher l'affichage de cette boîte de dialogue, nous avons choisi
l'outil at, souvent comparé à cron, mais dont la finalité
diffère légèrement. cron est utilisé pour des tâches régulières,
répétées. Exemples : tous les jours à 6h du matin, tous les week-end, toutes les
minutes, etc. at planifie une tâche à exécution unique. Une fois
accomplie, elle est effacée de la liste. at présente également plus de
souplesse dans la déclaration des événements. Ainsi, l'on pourra planifier une
tâche pour le 7 juillet 2004 à 10h45, ou encore pour dans un mois, deux jours et
six heures à partir de maintenant. Dans notre script, nous allons utiliser les
deux approches.
Pour la saisie des pense-bêtes nous proposons également l'utilisation de Xdialog et l'affichage successif de trois boîtes de dialogue : la première vous demande le texte à rappeler. La seconde est une boîte de type calendrier vous permettant de choisir facilement la date. Enfin la troisième vous demande l'heure avec une boîte adaptée.
La pratique
Nous supposons que vous savez manipuler Xdialog. Si ce n'est pas le cas, reportez-vous à l'article d'introduction, dans ce même magazine. Ici, nous allons utiliser systématiquement deux options (ligne 5) :
-stdoutredirige les données produites par Xdialog sur la sortie standard, ainsi l'on pourra les récupérer dans une variable ;-title Pense-bêtepour l'esthétique, cela permet de personnaliser la fenêtre en y adjoignant un titre.
Posez le décor
Chaque pense-bête sera dirigé par un script que nous allons créer à la volée lors de l'enregistrement. C'est ensuite ce script qui sera appelé en temps voulus pour afficher la boîte de dialogue de rappel.
Nous avons besoin d'un point de stockage pour tous les scripts qui correspondent
à tous les pense-bêtes que vous aurez besoin de créer. Nous choisissons pour
cela le répertoire .pensebete situé à la racine de votre répertoire
personnel et nous définissons la variable pensebetedir (ligne 4).
Lors de la création d'un nouveau pense-bête, nous devons vérifier
systématiquement que le répertoire existe bien. C'est ce que nous faisons à la
ligne 8: le test -d vérifie l'existence du répertoire
$pensebetedir. Si le test échoue, la commande mkdir est
exécutée.
Récupérez les données
Attaquons la partie qui sera visible à l'utilisation : la saisie du pense-bête
au moyen des boîtes de dialogue successives. Pour chaque boîte nous récupérons
le résultat dans une variable différente. Ainsi, $message est
renseigné par une inputbox (boîte simple de saisie de texte) et
contient le texte de votre pense-bête. $date renferme la date
d'exécution au format jj/mm/aaaa (par exemple 17/05/2004) : c'est une boîte
calendrier qui permet de renseigner cette variable simplement. Enfin,
$heure contient l'heure de rappel au format hh:mm:ss (exemple :
13:22:32).
Tout cela se passe aux lignes 11 à 13. La syntaxe $(commande) permet de
récupérer le résultat de commande envoyé sur la sortie standard. Vous
remarquerez également les symboles && et || en fin de lignes. Ils
permettent de créer un lien entre les commandes en fonction du résultat
d'exécution de la précédente. Ainsi, dans la syntaxe cmd1 && cmd2,
cmd2 sera exécutée seulement si cmd1 s'achève avec succès. Si
cmd1 échoue, alors cmd2 est ignorée. À l'inverse, +cmd1
|| cmd2+ signifie que cmd2 sera appelée en cas d'échec de
cmd1.
Ici, cela se traduit par le fait que l'on affiche une nouvelle boîte de dialogue uniquement si l'on a bien validé la précédente. En cas d'échec de l'une des boîtes de dialogue, les autres sont ignorées et l'on passe directement à la ligne 14, provoquant ainsi une sortie brutale du programme. Notez que le code de sortie 0 signifie une fin normale : tout autre code indique une erreur.
Traitez les données
Les données de date et d'heure récupérées précédemment ne sont pas au bon format
pour la commande at. La date doit être au format anglais (mm/jj/aaaa)
et l'heure ne doit pas contenir les secondes. Nous allons donc procéder à
quelques réajustements.
La date tout d'abord. À la ligne 17 nous recomposons la date en découpant la
variable $date en trois morceaux que nous recollons ensuite dans un
ordre différent. Par exemple, la syntaxe ${date:3:3} permet d'extraire
de la variable $date trois caractères à partir du numéro 3 (n'oubliez pas
que le premier porte le numéro 0). Cela correspond donc au mois suivi du
caractère slash de séparation.
Pour l'heure, c'est plus simple. Il suffit juste de retirer le dernier
deux-points et tout ce qui suit. C'est exactement ce que nous faisons à la
ligne 18. La syntaxe ${variable%motif} permet de retirer la plus petite
occurrence de motif située dans la partie finale de variable.
Notre motif, ici, est :* qui correspond à un deux-points suivi de
n'importe quels caractères.
Créez un nouveau script
Pour déclencher nos pense-bêtes, nous avons besoin d'un script pour chacun qui
sera exécuté par at au moment voulu. Cependant, ce n'est pas vous qui
allez rédiger ces scripts, mais cela sera automatisé ; c'est d'ailleurs le but
de ce cas pratique.
Entre les lignes 22 à 28 de notre présent script nous avons le squelette des scripts créés à la volée. Nous reviendrons ensuite sur le contenu de ce squelette. Pour l'instant, intéressons-nous à la façon dont le script est créé.
Tout d'abord, le nom. Afin de garantir l'unicité de ce dernier, nous choisissons
d'utiliser le nombre de secondes écoulées depuis le 1er janvier 1970 à minuit.
Cela peut paraître étrange comme choix, mais cette donnée s'obtient simplement
par la commande date +%s et donne un nombre différent toutes les
secondes. À la ligne 21 nous définissons une variable composée de ce nombre
(qui du coup est considéré comme un nom de fichier) et du chemin absolu vers le
futur fichier de script.
Ensuite, la rédaction du script. La ligne 22 indique que nous allons écrire
(commande cat) vers le fichier $pensebetename (créé à la volée)
toutes les lignes qui suivent jusqu'à trouver l'étiquette « FIN ».
Le script de rappel
Détaillons maintenant ce script de rappel. Nous voulons proposer la possibilité
de se faire rappeler le même pense-bête un peu plus tard (par exemple dix
minutes plus tard). Nous utilisons donc une boîte à deux boutons
(yesno). Le bouton « Oui » correspond à l'acceptation de la
notification. Le bouton « Non » induira la reconduction du pense-bête pour dix
minutes supplémentaires. Comme la dénomination « Non » n'est pas des plus
explicite pour une telle action, nous allons modifier le texte de ce bouton :
-cancel-label "Rappel 10 min".
Si vous avez essayé de tester la boîte yesno, vous aurez sûrement
constaté qu'elle ne renvoie rien sur la sortie standard. En fait, il faut tester
le code de succès de l'application : de suite après avoir quitté la boîte de
dialogue, testez la valeur de la variable $?. Si vous avez pressé
« Oui », $? vaut 0. Si vous avez pressé « Non » (ou toute autre
dénomination, seul le bouton importe), le résultat sera 1.
Nous testons donc cette valeur à la ligne 24. Le signe dollar est précédé d'un
anti-slash, car, lors de l'écriture du fichier il ne doit pas être interprété
comme c'est le cas pour $message ou $dlg_cmd. Il doit être
écrit tel quel, donc il faut le protéger. Si $? vaut 1, alors nous
reconduisons l'exécution de ce script pour dans dix minutes à partir de
maintenant (now + 10 min). Sinon, nous pouvons effacer le script.
Programmez l'appel
Détaillons à présent la commande at. Elle est employée par deux fois
aux lignes 25 et 31. La syntaxe est très simple : soit vous précisez une heure
et une date précise (ligne 31), soit vous donnez un décalage par rapport à une
date précise (l'instant présent étant désigné par le mot-clé now) comme
à la ligne 25.
L'option -f permet de préciser un nom de script à exécuter le moment
venu.
Le source
[bash]
1 #!/bin/bash
2
3 # Variables locales
4 pensebetedir=$HOME/.pensebete
5 dlg_cmd='Xdialog --stdout --title Pense-bête'
6
7 # Vérification de l'existence du répertoire des pense-bêtes
8 [ -d $pensebetedir ] || mkdir $pensebetedir
9
10 # Récupération des données auprès de l'utilisateur
11 message=$($dlg_cmd --inputbox "Entrez votre pense-bête" 0 0) &&
12 date=$($dlg_cmd --calendar "Entrez la date de rappel" 0 0 0 0 0) &&
13 heure=$($dlg_cmd --timebox "Entrez l'heure de rappel" 0 0) ||
14 exit 1
15
16 # Aménagement des données pour at
17 date=${date:3:3}${date:0:3}${date:6}
18 heure=${heure%:*}
19
20 # Création du script qui sera appelé par at
21 pensebetename=$pensebetedir/$(date +%s)
22 cat >>$pensebetename << FIN
23 $dlg_cmd --cancel-label "Rappel 10 min" --display ":0" --yesno "$message" 0 0
24 if [ \$? == 1 ]
25 then at -f $pensebetename now + 10 min
26 else rm $pensebetename
27 fi
28 FIN
29
30 # Enregistrement auprès de at
31 at -f $pensebetename $heure $date
Exemple
Executez le script :
pensbet
Puis renseignez le message :

le jour

et l'heure où ce message devra apparaître sur votre écran

Le script généré sera celui-ci :
[bash] Xdialog --stdout --title Pense-bête --cancel-label "Rappel 10 min" --display ":0" --yesno "Acheter du pain et du fromage" 0 0 if [ $? == 1 ] then at -f /home/bdc/.pensebete/1084811787 now + 10 min else rm /home/bdc/.pensebete/1084811787 fi
Et il produira cette fenêtre le moment venu :

Documentation
- man Xdialog, man at, man bash
- syntaxe des éléments temporels pour at : consultez le fichier
/usr/share/doc/at/timespec - Xdialog


Commentaires
Aucun commentaire pour le moment.
Ajouter un commentaire
Les commentaires pour ce billet sont fermés.