Ismerkedés a Whiptail dialóguskészítő programmal

botond küldte be 2018. 10. 22., h – 02:44 időpontban

Az 1. oldal tartalma

 

Bevezető

Shell vagy Bash szkriptek készítésénél előnyös, ha a munkánkat megfűszerezzük vizuális elemekkel, melyeknek köszönhetően felhasználhatóbbá, kényelmesebbé és látványosabbá válnak programjaink. Továbbá fontos még az is, hogy kódjaink hordozhatóak maradjanak, hogy más számítógépeken is futtathatóak legyenek. Erre a célra kiválóan alkalmas a Whiptail program, mely bármelyik Linux disztribúcióra telepíthető, így nem jelent akadályt más helyeken is futtatni programjainkat, amikben a whiptail paranccsal hoztunk létre dialógusablakokat.

Ebben a leírásban megismerkedünk a whiptail paranccsal és elkészítjük az alap dialógus ablak példányokat. A Whiptail program nem újdonság, de magyar nyelven nem nagyon találtam átfogó leírást a működtetéséről, így remélem hasznos lesz ez az ismertető.

 

 

Telepítés

Ha gépünkön még nincs telepítve a whiptail csomag, akkor ezt könnyen megtehetjük, root-ként adjuk ki az alábbi telepítő APT parancsot (Debian disztribúciók esetén):

apt-get install whiptail

 

Dialógusok

A program többféle dialógusablak fajtát kínál, amelyek különböző feladatokra jók:

Infódoboz (Infobox)

Az infódoboz vagy rendes nevén infobox egy egyszerű panel, ami nem akasztja meg a programfutást, csak kirajzolja az ablakot a megadott címmel és tartalommal és kilép. Megjelenítését a program --infobox paraméterével végezhetjük. Szintaktikája:

--infobox <szöveg> <magasság> <szélesség>
  • Szöveg: A panelen megjelenő szöveg
  • Magasság: A panel magassága. Beleértve a kereteket is.
  • Szélesség: A panel szélessége. Beleértve a kereteket is.

Egyszerű példa:

whiptail --title "Példa infópanel címe" --infobox "Példa infópanel tartalma" 8 40

Az eredmény:

Whiptail - Infobox bemutatása

És itt meg is állhatunk egy kicsit, mert ha az iménti parancsot beírjuk egy x terminálba, vagy akár a Putty-ba, akkor nem fog történni semmi, mert a program egy ismert hibája miatt ez a funkció nem működik xterm-eken, hanem csak rendes konzolon. Így én ezt most az egyik VirtualBox gépemen csalogattam elő konzol módban, amiről tudtam képernyőképet készíteni.

Tehát lényegében az infódoboz arra jó, hogy megjelenítjük, majd utána fut tovább a programkód, így el tudunk közben végezni más teendőket is, majd amikor írunk a kimenetre, akkor tűntetjük el, stb.

De mivel csak konzolon működik, ezért csak érdekességként tekintsünk rá, kerüljük a használatát és inkább használjuk helyette például a Message box-ot.

Üzenetdoboz (Message box)

Az üzenetdoboz, eredeti nevén Message box arra szolgál, hogy a megjelenített szövegblak aljára kitesz egy Ok gombot, amivel megakasztja a programfutást és vár a felhasználó interakciójára. Használhatjuk például fontos információk megjelenítésére, amit mindenképp látnia kell a felhasználónak, mielőtt továbbhaladhatna.

Használata a --msgbox paraméterrel történik:

--msgbox <szöveg> <magasság> <szélesség>
  • Szöveg: A panelen megjelenő szöveg
  • Magasság: A panel magassága. Beleértve a kereteket is.
  • Szélesség: A panel szélessége. Beleértve a kereteket is.

Egyszerű példa:

whiptail --title "Példa üzenetdoboz" --msgbox "Ez az üzenetdoboz tartalma. Ok-ra nyomva mehet tovább..." 8 60

A whiptail parancsnak van még egy backtitle opciója is, amivel az egész ablaknak vagy képernyőnek adhatunk címet, ami a bal felső sarokban jelenik meg. Ha már van egy ilyen lehetőség is, akkor tegyük bele ezt is:

whiptail \
    --backtitle "Ablak főcíme" \
    --title "Példa üzenetdoboz" \
    --msgbox "Ez az üzenetdoboz tartalma. Ok-ra nyomva mehet tovább..." \
    8 60

Ennek a kimenete pedig:

Whiptail - Message box bemutatása

Ahogy a képen látható, ez már egy PuTTY ablakban jelenik meg, tehát innentől már kompatibilisek a funkciók minden terminállal.

Ennél az ablaktípusnál már van interakció így a felhasználónak is van választása hogy az Ok gombot nyomja meg vagy az ESC billentyűt. Mindkét esetben kilép a whiptail program, azonban más hiba állapotokat generál, amit a $? változóban kapunk vissza. Ha az Ok gombot nyomja meg, akkor a hibakód=0, ha pedig az ESC billentyűvel lép ki, akkor pedig 255-ös kódot kapunk. Így a programunkban ki tudjuk értékelni a kilépés állapotát, majd ennek megfelelően tudjuk folytatni a futását.

Erre egy egyszerű példa:

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash
whiptail \
    --backtitle "Ablak főcíme" \
    --title "Példa üzenetdoboz" \
    --msgbox "Ez az üzenetdoboz tartalma. Ok-ra nyomva mehet tovább..." \
    8 60
    
if [[ $? == 0 ]] ; then
    echo "Kilépés Ok gombbal."
else
    echo "Kilépés ESC billentyűvel"
fi

Igen/nem kérdeződoboz (Yes/no box)

Ennek a dialógus típusnak a lényege, hogy kérdéseket tehetünk fel a felhasználónak, amire igen vagy nem választ adhat, de itt is fennáll az ESC billentyűvel történő kilépés lehetősége.

A kérdeződobozt a --yesno paraméterrel hozhatjuk létre:

--yesno  <szöveg> <magasság> <szélesség>
  • Szöveg: A panelen megjelenő szöveg
  • Magasság: A panel magassága. Beleértve a kereteket is.
  • Szélesség: A panel szélessége. Beleértve a kereteket is.

Az alábbi példában feltesszük a kérdést a kérdező dobozzal, majd egy case elágazással kiértékeljük a felhasználó válaszát:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/bin/bash
whiptail \
    --backtitle "Ablak főcíme" \
    --title "Példa kérdés doboz" \
    --yesno "Igen/nem választási példa. Melyiket választja?" \
    8 60
 
# Kiértékelés
case $? in
0)
    echo "Kilépés az Igen gombbal"
;;
1)
    echo "Kilépés a Nem gombbal"
;;
255)
    echo "Kilépés az ESC billentyűvel"
;;
*)
    # Ez nem fordulhat elő, csak betettem, hogy szabályosak legyünk...
    echo "Érvénytelen hibakód."
;;
esac

Whiptail - Yes/No box bemutatása

Itt érdemes még egy külső ciklust is alkalmazni, amivel "visszatéríthetjük" a felhasználót újból a kérdésre, ha az ESC gombot nyomta meg. Valamint betettem még egy beágyazott üzenet ablakot is, amin tájékoztatjuk a felhasználót az érvénytelen (ESC) választásról:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/bin/bash
while true; do      # Végtelen ciklus indul
    whiptail \
        --backtitle "Ablak főcíme" \
        --title "Példa kérdés doboz" \
        --yesno "Igen/nem választási példa. Melyiket választja?" \
        8 60
 
    # Kiértékelés
    case $? in
    0)
        echo "Érvényes választás: Igen"
        break       # kilépés a végtelen ciklusból
    ;;
    1)
        echo "Érvényes választás: Nem"
        break       # kilépés a végtelen ciklusból
    ;;
    255)            # Ha ESC gombot nyomtak, akkor
        # Beágyazott whiptail hibaüzenet ablak, amiben kiírjuk, hogy
        # érvénytelen volt a választás, és ezt még le kell okéznia
        whiptail \
            --backtitle "Hiba!" \
            --title "Érvénytelen választás!" \
            --msgbox "Kérem adja meg valamelyik érvényes választ!" \
            8 60
        # És itt nem lépünk ki a ciklusból hogy újra lefuttassa az egészet
    ;;
    *)
        # Ez nem fordulhat elő, csak betettem, hogy szabályosak legyünk...
        echo "Érvénytelen hibakód."
    ;;
    esac
done

Kicsit megcifráztam, de így már biztosak lehetünk benne, hogy nem eredményez hibás működést a programunkban az ESC billentyű lenyomása, valamint a felhasználót is tájékoztatjuk az érvénytelen ESC használatáról.

 

 

Szövegbeviteli mező (Input box)

A szövegbeviteli mező segítségével tudunk szöveges választ bekérni a felhasználótól. A --inputbox paraméterrel hozhatjuk létre:

--inputbox <szöveg> <magasság> <szélesség> [alapszöveg]
  • Szöveg: A panelen megjelenő szöveg
  • Magasság: A panel magassága. Beleértve a kereteket is.
  • Szélesség: A panel szélessége. Beleértve a kereteket is.
  • Alapszöveg: Itt megadhatunk alapértelmezett szöveget is az inputbox paraméter utolsó értékeként, ami még funkcionálisabbá teszi a szöveg bekérő panelt.

Egyszerű példa:

1
2
3
4
5
#!/bin/bash
whiptail \
    --backtitle "Ablak főcíme" \
    --title "Példa üzenetdoboz" \
    --inputbox "Kérdés .... ?" 8 40 "alapértelmezett szöveg"

Whiptail - Input box bemutatása

Itt ha az Ok gombot nyomják meg, akkor kilép és megjelenik a beadott szöveg. Ha a mégse gombot vagy az ESC billentyűt nyomják, akkor pedig nem kerül ki a mezőben lévő szöveg.

Az előző paneleknél megszokott módon visszakapjuk a hibakód ($?) változóban a lenyomott gombnak megfelelő értéket: Ok gomb: 0, Mégse gomb: 1 és az ESC billentyűre a 255-ös értéket olvashatjuk ki a futás után. De mi a helyzet a begépelt szöveggel?

Ha a begépelt szöveget egy változóba szeretnénk elkapni, akkor kicsit trükközni kell, mivel a whiptail a szabványos hibakimenetre (stderr) írja a mezőben lévő karakterláncot. A szabványos ki és bemeneteket (stdout, stdin) az ablak megjelenítésére és a karakterek bekérésére használja, így csak a hibakimenet marad a bevitt érték továbbítására.

A subshell-ekben lefuttatott parancsoknak viszont csak a szabványos kimenetei (stdout) kerülnek kiadásra külső shell számára, ezért a dialógus futtatásakor fel kell cserélni a kimenetet a hibakimenettel, hogy ki tudjuk nyerni a bekért szöveget. Ez egy rövidített példával így néz ki:

valasz=$(whiptail --inputbox "Kérdés?" 8 40 "Alap" --title "Ablakcím" 3>&1 1>&2 2>&3)
echo $valasz

Tehát így lehet kiolvasni változóba az Input Box-ból a begépelt szöveget.

Illetve van még lehetőség arra is, hogy a felhasználó által beírt választ közvetlenül egy fájlba mentsük például későbbi feldolgozás céljából:

whiptail --inputbox "Kérdés?" 8 40 "Alap" --title "Ablakcím" 2>tmpfile

Itt is a hibakimenetet (stderr) irányítjuk át egy tetszőleges fájlba.

Most nem bonyolítom a gombok kiértékelő részével és az ESC billentyű lekezelésével a dolgot, ezeket a körítéseket itt is ugyanígy lehet alkalmazni, mint a fenti kérdeződoboz esetén.

Szövegdoboz (Text box)

A szövegdoboz segítségével szöveges fájlok tartalmát jeleníthetjük meg egy dialógusablakban. Használata praktikus, mivel a szöveges tartalom külön van a programkódtól, így módosítása is könnyebb kívülről, valamint a programkód méretét sem növeljük szöveges tartalmakkal és kódunk is olvashatóbb marad.

Használata a --textbox paraméterrel történik:

--textbox <fájlnév> <magasság> <szélesség>
  • Fájlnév: A beolvasandó szövegfájl
  • Magasság: A panel magassága. Beleértve a kereteket is.
  • Szélesség: A panel szélessége. Beleértve a kereteket is.

Kipróbálásához hozzunk létre egy új szövegfájlt pl. a nano szerkesztővel:

nano textbox_file

És töltsük fel mondjuk néhány mondatnyi Lorem Ipsum szöveggel:

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Ezután készítsük el a a dialógust megjelenítő Bash programunkat:

1
2
3
4
5
#!/bin/bash
whiptail \
    --backtitle "Ablak főcíme" \
    --title "Példa szövegdoboz" \
    --textbox ./textbox_file 16 60

Whiptail - Textbox bemutatása

Itt is ugyanúgy kiolvasható utána a hibakód változó ($?), és az értéknek megfelelően lehet folytatni a program futását (Ok=0, ESC=255), így például az ESC gomb lenyomására le is állíthatjuk az egész programot, stb.

Valamint itt még érdemes kihasználni a whiptail scrolltext opcióját is, amivel  hosszabb szövegtartalmakat görgethető ablakban jeleníthetjük meg.

Először duplázzuk meg a szöveget a szövegfájlban, hogy szemléletesebb legyen a példa:

echo $(cat ./textbox_file) >> ./textbox_file

És a program kiegészítve a scrolltext kapcsolóval:

1
2
3
4
5
6
#!/bin/bash
whiptail \
    --backtitle "Ablak főcíme" \
    --title "Példa szövegdoboz" \
    --textbox ./textbox_file 16 60 \
    --scrolltext

Whiptail - Görgethető textbox bemutatása

Bár maga a görgető elem most éppen nem akar megjelenni (több gépen is próbáltam most), de ettől függetlenül a kurzor billentyűkkel szépen lehet görgetni a szöveget. Lehet, hogy a nálam lévő verzióval van a baj, hogy csak egy kimaradás látszódik a dialógus ablak keretének jobb felén, de korábban megjelent más szituációban. A lényeg, hogy ettől függetlenül működik a görgetés.

 

Lapozó

Ez a leírás több oldalból áll: