(X)dialog: Pratende shells

ArticleCategory: [Choose a category, translators: do not translate this, see list below for available categories]

UNIXBasics

AuthorImage:[Here we need a little image from you]

[Katja en Guido Socher]

TranslationInfo:[Author + translation history. mailto: or http://homepage]

original in en Katja en Guido Socher 

en to nl Guus Snijders

AboutTheAuthor:[A small biography about the author]

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.

Abstract:[Here you write a little summary]

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.

ArticleIllustration:[One image that will end up at the top of the article]

[Illustratie]

ArticleBody:[The main part of the article]

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:

[yes/no Xdialog]

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.

[yes/no dialog]

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:

[pppdialout met xdialog]
[pppdialout met xdialog]

... met de curses gebaseerde dialog in de terminal:

[pppdialout met dialog]
[pppdialout met dialog]

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