Je vous avais promis la dernière fois un couple langage/kit graphique classique ... J'ai menti ! Je vous présente bash/(x)dialog.
Voyons en bash comment obtenir le programme générique à réaliser dans cette série d'articles : demander son nom à l'utilisateur et lui dire bonjour.
Tapez ceci dans un fichier bonjour_bash :
#!/bin/bash echo Tapez votre nom : read nom echo Bonjour $nom !
Il nous faut ensuite rendre le script exécutable et le lancer :
zazou@ZazouMobile:~/devel_bash$ chmod a+x bonjour_bash zazou@ZazouMobile:~/devel_bash$ ./bonjour_bash Tapez votre nom : Xavier Garreau Bonjour Xavier Garreau !
Voila ! Nous avons les bases de cet article ;-), bien que la suite n'ait plus grand chose à voir au niveau du code ...
Le contenu de ce script est très simple, la première ligne sert à savoir quel interpréteur on doit utiliser pour l'exécuter,
les deux lignes commençant par echo
affichent le texte qui suit, en remplaçant les variables par leurs valeurs.
L'instruction read
attend une ligne de l'utilisateur et en place le contenu dans la variable indiquée ensuite (il y a d'autres
options : man bash)
Bash et dialog sont utilisés dans toutes les distributions que j'ai fréquentées. Vous connaissez tous ces interfaces si vous avez installé une slackware, une debian, une tclinux ou si vous avez déjà utilisé une MandrakeMove ou que vous connaissez linux depuis longtemps car presque toutes les distributions sont passées par une installation basée sur bash/dialog. Certaines l'utilisent toujours et dans bien des cas, c'est heureux pour les machines n'ayant pas trop de puissance.
dialog permet d'afficher des boîtes de dialogue dans votre console. C'est simple, et efficace. dialog est par exemple utilisé sous une forme simplifiée, lxdialog, pour la configuration du kernel (make menuconfig).
Oui mais pourquoi a-t-on besoin de dialog ? On peut faire la même chose en "langage quelconque/toolkit graphique quelconque". A cette question, plusieurs réponses. La première, "pour voir plus loin, ce qui se cache derrière ce que l'on sait" ... La seconde est liée à d'éventuelles contraintes techniques, on n'a pas toujours sous la main un écran de 24 pouces avec le dri activé sur un XFree 6.4 avec les dernières libs gtk+ 3.6.3rc4 pour faire une géniale interface communiquant via corba_ng (pour next generation). Bref, pouvoir faire un outil un tant soit peu évolué, rapidement et sans besoin de ressources prohibitif.
Trêve de discussions, place au code :
#!/bin/bash nom=`dialog --backtitle "Bonjour en bash/dialog" \ --title " La question " \ --inputbox "Entrez votre prénom :" 0 0 \ 2>&1` if [ $? = 0 ]; then dialog --backtitle "Bonjour en bash/dialog" \ --title " Le Bonjour " \ --msgbox "\nBonjour $nom !" 10 30 fi
Notre première instruction appelle directement le programme dialog. A chaque appel de dialog correspond
par défaut un écran avec un "dialogue". On voit ici 2 arguments. backtitle
sert à préciser le titre qui
doit apparaître en haut de l'écran. title
permet, lui, de spécifier le titre du dialogue. Enfin, on choisit le type de
dialogue à générer. Ici, on veut un dialogue acceptant une entrée de l'utilisateur, on utilise donc
inputbox
. Ce terme doit être suivi d'un texte explicatif, de la hauteur et la largeur du widget, en caractères ...
Indiquer des tailles nulles permet de laisser dialog
choisir des valeurs appropriées pour ces dernières.
dialog
renvoie un code de retour dépendant du bouton cliqué, pour "oui", "ok", "accepter", ... c'est 0.
Les informations entrées par l'utilisateur sont, elles, envoyées sur le flux d'erreur standard (2). en ajoutant 2>&1
,
on redirige ce flux vers la sortie standard. On récupère ainsi la chaîne saisie par l'utilisateur dans la variable
nom
.
Dans la suite de ce "long" script, on teste la valeur de retour de l'expression dialog
précédente $?
et,
si l'utilisateur a cliqué sur "Accepter", on affiche un dialogue de salutation, une "boîte à message", msgbox
,
laquelle prend les mêmes arguments que le dialogue précédent. La seule différence réside dans le choix de la taille, que l'on
impose.
Les fins connaisseurs apprécieront le fait que l'on puisse cliquer sur les boutons avec la souris ...
Bon ok, ok, j'avais dit toolkit graphique et certains d'entre vous ont compris par là, "des fenêtres où qu'on clique dessus avec le mulot". Soit, j'appelle à ma rescousse le programme Xdialog pour les adeptes du clickodrome ...
Contrairement à dialog, Xdialog n'est pas souvent installé par défaut par vos distributions préférées... Il vous faut donc
le télécharger, éventuellement le compiler et l'installer. Sous debian, c'est affreusement simple, il suffit de taper
apt-get install xdialog
. Pour les autres, il existe surement des paquets à installer également mais dans le cas
contraire, il reste la possibilité de compiler vous même les sources de ce fabuleux programme ... Commencez par télécharger
les sources sur la page du projet (http://xdialog.dyns.net/) et le trio ./configure ; make ; make install
habituel fera l'affaire pour vous procurer une installation fonctionnelle ...
Xdialog s'appuie sur gtk+ pour vous procurer un confort visuel "amélioré". Personnellement, je préfère la version ncurses,
c'est plus "root" mais bon, chacun ses choix, on est adepte de make menuconfig
ou on ne l'est pas ;-) ...
L'important est que vous devrez avoir une installation de gtk1.x et gtk-config (à l'heure actuelle) pour utiliser Xdialog.
Pour utiliser Xdialog en lieu et place de dialog, vous n'avez qu'à remplacer toutes les occurences de dialog par Xdialog ...
Comme bien souvent une image parle plus qu'un long discours ...
Je ne résiste pas à l'envie de vous montrer quelques autres exemples de widgets. Cette liste n'est toutefois pas exhaustive ... Découvrez les autres vous mêmes !
Ci-dessous le code d'un viewer de fichier très simple mais fonctionnel ...
#!/bin/bash if [ "$1" != "" ]; then if [ -f $1 ]; then dialog --backtitle "Widgets de bash dialog" \ --title " Ze viewer : $1" \ --textbox $1 18 70 else echo "Fichier introuvable"; fi else echo USAGE: $0 fichier fi
Cette année, mon anniversaire sera le 4/4/4, mais ça se voit mieux comme ça :
dialog --backtitle "Widgets de bash dialog" \ --title "Anniversaire" \ --calendar "" 0 0 4 4 2004
Voilà un élément très utilisé parmi les possibilités offertes par dialog. La barre de progression ou gauge
...
Le programme ci-dessous fonctionne "à peu près" comme cp
pour les fichiers à ceci près qu'il affiche une barre de
défilement.
Pour afficher une barre de progression, on utilise dialog --gauge
. Pour mettre à jour cette barre,
il faut envoyer sur l'entrée standard de dialog les différents pourcentages à afficher. Lorsqu'on ferme l'entrée standard,
dialog
rend la main.
Il faut donc rediriger la sortie standard d'un sous-shell dans l'entrée de dialog
.
Par exemple, le code ci-dessous affiche une barre de défilement à 25% attends une seconde, la mets à jour à 50, puis quitte :
(echo 25 ; sleep 1 ; echo 50) | dialog --gauge "" 0 0
.
Voici le script de copie de fichier avec état d'avancement.
#!/bin/bash if [ "$1" != "" -a "$2" != "" ]; then if [ -f $1 ]; then src=$1 size=`ls -al $src | awk '{print int(($5/512)+(($5%512)?1:0))}'` src_name=`find $src -printf %f` else echo "Fichier source introuvable" >2 exit 1 fi if [ -f $2 ]; then dest=$2 else if [ -d $2 ]; then dest=$2/$src_name else dest=$2 touch $dest 2> /dev/null if [ $? != 0 ]; then echo "Destination invalide" >&2 exit 1 fi fi fi echo $src $dest $size chunk_size=$(($size/100)) if [ $chunk_size -lt 1 ]; then cp $src $dest exit 0 fi copied=0 (while [ $copied -lt $size ]; do dd if=$src of=$dest bs=512 count=$chunk_size skip=$copied seek=$copied >/dev/null 2>&1 copied=$(($copied+$chunk_size)) echo $(((100*$copied)/$size)) done) | dialog --backtitle "Widgets de bash dialog" --title " Copie en cours " --gauge "$src\n> $dest " 10 60 0 else echo USAGE: $0 fichier_src dest fi
NB: Les accrocs du tcl peuvent remplacer :
size=`ls -al $src | awk '{print int(($5/512)+(($5%512)?1:0))}'`
par
size=`echo "puts [eval expr int(ceil([file size $src]./512))]" | tclsh`
(Merci David)
@+
Xavier Garreau - <xavier@xgarreau.org>
http://www.xgarreau.org/
Ingénieur de recherche PRIM'TIME TECHNOLOGY
http://www.prim-time.fr/
Membre fondateur du ROCHELUG
http://www.rochelug.org/
a+