|
LinuxFocus article number 267
http://linuxfocus.org
|
|
|
|
|
door Katja en Guido Socher <katja/at/linuxfocusorg guido/at/linuxfocus.org>
Over de auteur:
Katja is de Duitse editor van LinuxFocus. Ze houdt van Tux,
film & fotografie en de zee. Haar homepage vindt je
hier. Guido is reeds lang een Linux fan en houdt van Linux omdat het
is ontworpen door eerlijke, open mensen. Dit is een van de redenen
waarom we het open source noemen. Zijn homepage bevindt zich op
linuxfocus.org/~guido.
Vertaald naar het Nederlands door:
Guus Snijders <ghs(at)linuxfocus.org>
|
(X)dialog: Pratende shells
Kort:
Xdialog en dialog zijn 2 klassieke utillities om je shell scripts te voorzien
van een grafische gebruikers interface.
Enige kennis van het programmeren van de shell is vereist om dit artikel
te begrijpen. Om meer te leren over de basics van shell programmeren
kun je ons artikel over
Programmeren in de shell lezen.
_________________ _________________ _________________
|
Introductie
De Unix shell op zich is een zeer productieve omgeving en werkt
heel goed zonder een gebruikersinterface (Graphical User Interface, GUI).
In sommige gevallen kan het echter wenselijk zijn om een grafische dialoog
te hebben met de gebruiker. Denk bijvoorbeeld aan de installatie-dialoog van
een programma. Die hebben vaak een aantal mogelijkheden voor wat
betreft de instellingen en je kunt de doeldirectory selecteren...
En daar is (X)dialog...
Met dialog en Xdialog kun je een grafische applicatie ontwikkelen door gewoon
een kort shell scriptje te schrijven. Dialog is een puur terminal-gebaseerd
programma en Xdialog is een X11 programma.
Hier is een voorbeeld:
Je kunt de volgende regels in een shell venster (xterm, konsole...)
typen (of kopiëren en plakken):
bash
Xdialog --yesno "Do you want to learn more about Xdialog?" 0 0;\
case $? in
0)
echo "Result: Yes chosen.";;
1)
echo "Result: No chosen.";;
255)
echo "ESC pressed.";;
esac
Het venster dat zal verschijnen ziet er zo uit:
Als je dialog gebruikt in plaats van Xdialog (verwijder de X op de
tweede regel in het script hierboven) dan krijg je een curses-gebaseerde
applicatie die in dezelfde xterm zal draaien en dus niet een apart venster
opent. In sommige gevallen komt dit beter uit voor een shell script, daar het
in de terminal blijft draaien.
Vooral als je het op afstand wilt draaien met een hoeveelheid
verschillende hosts waar directe IP routing niet beschikbaar is. In dit geval zal
dialog werken, maar zul je niet in staat zijn een X11 applicatie zoals Xdialog te
starten.
Bovenstaande was een nauwelijks bruikbaar voorbeeld van dialog/Xdialog,
maar laat wel zien hoe makkelijk het is om een eenvoudige grafische
dialoog te programmeren.
Er zijn meer interessante zogenaamde dialoog'boxen'. Boxen als kalender, menus, bestandsbeheer,
voorgangsbalk, tekst invoer, bericht box, wachtwoord dialoog...
Je kunt gebruik maken van
dialog --help
of
Xdialog --help
...om een lijst van beschikbare dialoogboxen op te vragen. Xdialog beschikt
over iets meer boxen dan dialog.
Hoe het werkt
De dialoog boxen worden geconfigureerd op de commando regel.
dialog --yesno "tekst string" <hoogte>
<breedte>
Na dialog of Xdialog geef je de naam van het soort box
dat je wilt, gevolgd door specifieke parameters.
De yesno
box kent 3 parameters.
De <hoogte> en <breedte> kun je op nul zetten, in welk geval
de geometry van de box automatisch wordt aangepast aan de afmetingen
van de tekst. Het resultaat wordt geretourneerd als exit status aan het
script in de "$?" variabele. Als er meer is om te retourneren zoals bijv.
de namen van de geselecteerde opties, dan gebeurt dit via de
'standard error' output.
Standard error wordt normaal gesproken naar het scherm gestuurd maar is
om te leiden met "2>".
Een eenvoudige maar efficiënte oplossing.
Echte applicaties
Nu bekijken we een echte applicatie waar Xdialog/dialog een voordeel biedt boven
conventionele shell scripts: een menu waar je kunt kiezen uit verschillende
Internet Service Providers om uit te bellen naar het Internet. Dit script gebruikt
de ppp-on/ppp-off scripts van het Maart 2001 artikel Using different
ISPs for your Internet access. Het script draagt de naam pppdialout en
geeft een ander menu weer, afhankelijk van het feit of je online bent
of niet.
#!/bin/sh
#
#DIALOG=Xdialog
DIALOG=dialog
#
# name of your default isp:
defaultisp=maxnet
#
error()
{
echo "$1"
exit 2
}
help()
{
cat <<HELP
pppdialout -- select an ISP and dial out.
All available ISPs must have a config file in /etc/ppp/peers
pppdialout executes the ppp-on/ppp-off scripts as described
in http://linuxfocus.org/English/March2001/article192.shtml
pppdialout, copyright gpl, http://linuxfocus.org/English/November2002
HELP
exit 0
}
# parse command line:
while [ -n "$1" ]; do
case $1 in
-h) help;shift 1;; # function help is called
--) shift;break;; # end of options
-*) echo "error: no such option $1. -h for help";exit 1;;
*) break;;
esac
done
tempfile=/tmp/pppdialout.$$
trap "rm -f $tempfile" 1 2 5 15
# check if we have a ppp network interface
if /sbin/ifconfig | grep '^ppp' > /dev/null; then
# we are already online
$DIALOG --title "go offline" --yesno "Click YES to \
terminate the ppp connection" 0 0
rval="$?"
clear
if [ "$rval" = "0" ]; then
echo "running /etc/ppp/scripts/ppp-off ..."
/etc/ppp/scripts/ppp-off
fi
else
# no ppp connection found, go online
# get the names of all available ISP by listing /etc/ppp/peers
for f in `ls /etc/ppp/peers`; do
if [ -f "/etc/ppp/peers/$f" ]; then
isplist="$isplist $f =="
fi
done
[ -z "$isplist" ]&&error "No isp def found in /etc/ppp/peers"
#
$DIALOG --default-item "$defaultisp" --title "pppdialout" \
--menu "Please select one of\
the following ISPs for dialout" 0 0 0 $isplist 2> $tempfile
rval="$?" # return status, isp name will be in $tempfile
clear
if [ "$rval" = "0" ]; then
isp=`cat $tempfile`
echo "running /etc/ppp/scripts/ppp-on $isp..."
/etc/ppp/scripts/ppp-on "$isp"
else
echo "Cancel..."
fi
rm -f $tempfile
fi
# end of pppdialout
De werking van het script:
Eerst definiëren we een paar functies, error en help,
daarna wordt
er gekeken naar commandregel opties en vervolgens wordt er een
naam voor het tijdelijke bestand gedefiniëerd. (/tmp/pppdialout.$$). $$
is de naam van het huidige proces en is een uniek nummer voor iedere
computer. Het 'trap' statement wordt uitgevoerd als het programma abnormaal
wordt beëindigd (bijvoorbeeld als de gebruiker op [CTRL] + [C] drukt) en
verwijdert in ons geval het tijdelijke bestand.
Daarna controleren we of we reeds online zijn of niet (commando: /sbin/ifconfig
| grep '^ppp'). Als we online zijn, openen we een yesno-box, dezelfde als die
we eerder hierboven hebben gezien, en vragen we aan de gebruiker of hij/zij
offline wil gaan. Als we niet online zijn, wordt er een menu box geopend. We
krijgen alle beschikbare ISP's door een lijst weer te geven van alle bestanden
in /etc/ppp/peers (ls /etc/ppp/peers). De syntax van de menu box is:
dialog --menu "tekst" <hoogte>
<breedte> <menu hoogte> <tag1>
<beschrijving> ...
De <hoogte>, <breedte> en <menu hoogte> zijn
weer op nul gezet (automatische afmetingen, zie boven) en dan verwacht het
programma paren van strings (<tag1> <beschrijving>). In dit geval
hebben we niet echt een beschrijving, dus vullen we iets betekenisloos
in (== in dit geval). De data in de 'variabele' isplist zal er zo uitzien:
isp1 == isp2 == isp3 ==
Het resultaat van de keus van de gebruiker wordt door (X)dialog geprint op
standaard error (stderr). Het shell commando "2> $tmpfile" schrijft het weg
naar ons tijdelijke bestand. De menu box biedt ook de mogelijkheid om op
cancel te drukken. Daarvoor moeten we $? (exit status) checken om te achterhalen
welke knop is ingedrukt.
Ok, genoeg theorie. Hier kun je zien hoe het er uit komt te zien
... als aardige GTK GUI met Xdialog:
... met de curses gebaseerde dialog in de terminal:
Meer toepassingen
We hebben nog een toepassing voor je. Het is genaamd mktgz en
gebruikt een checklist box van Xdialog. De gewone terminal-gebaseerde
dialog kent geen 'checklist', daardoor werkt het alleen met Xdialog.
Mktgz kun je gebruiken om tar.gz pakketten te maken.
mktgz jouwpakket .
Dit geeft alle bestanden in de huidige werkdirectory weer (".")
zodat je diegene kunt selecteren die je in je jouwpakket.tar.gz pakket
wilt hebben. Je kunt het hier (mktgz.txt) downloaden.
We zullen niet regel-voor-regel door de code gaan, daar je al genoeg
zou moeten weten om het script te lezen.
Xdialog en dialog komen met een directory genaamd "samples" waar
je meer voorbeelden kunt vinden (RedHat 7.3 slaat deze op onder
/usr/share/doc/Xdialog-2.0.5/samples).
Wees echter wel voorzichtig, daar sommige echte taken uitvoeren, en
niet pure demo applicaties zijn.
Conclusie
Xdialog en dialog bieden een aantal verschillende dialoogvensters.
Niet alle daarvan zijn altijd van toepaasing voor alle types shell scripts.
De shell zelf is een zeer krachtige omgeving. Een pad completeren met
de tab-toets kan een stuk sneller zijn dan door de verschillende directories
klikken met een GUI.
Vooral de mogelijkheid om commando's te combineren en om te
leiden maken het tot een krachtig stuk gereedschap. Iets als:
grep -i "eenstring" file.txt | sort | uniq | wc -l
(voor diegenen zonder ervaring met UNIX shells: dit telt
alle regels in file.txt waarin de string "eenstring" voorkomt)
is mogelijk doordat alle commando's worden
gestuurd met behulp van commandoregel argumenten. Met andere woorden:
ze zullen niet stoppen om de gebruiker te vragen of hij door wil gaan.
Er zijn echter applicaties waarbij grafische dialogen echt bruikbaar zijn.
Xdialog en dialog zijn heel eenvoudig in gebruik, maar zijn natuurlijk niet zo
krachtig als een echte grafische applicatie. Ze vullen het gat op tussen een
puur ASCII shell script en een volledig grafische applicatie.
Waar Xdialog en Dialog te verkrijgen?
De CDs van je Linux distributie zijn de eerste plaats om te zoeken naar dialog en/of
Xdialog. Het zou kunnen zijn dat ze reeds geïnstalleerd zijn op je computer (vraag het
je computer: bijv. rpm -qil Xdialog, dpkg -L Xdialog).
De homepage van Xdialog is:
http://www.chez.com/godefroy/
en dialog is te vinden op
http://hightek.org/dialog/
Hier kun je dialog/Xdialog natuurlijk ook downloaden.
Referenties
2005-01-14, generated by lfparser_pdf version 2.51