Du kan integrera GUI-element, som fönster, knappar, radioväljare och förloppsindikatorer, direkt i dina Bash-skript. Utforska hur du använder Zenity-verktygslådan för att ge dina skript en mer visuellt tilltalande och användarvänlig upplevelse. Vi visar dig hur du gör.
Bash-skriptning är ett kraftfullt programmeringsverktyg. Eftersom det är inbyggt i Bash-skalet är det lätt tillgängligt för alla. Det är också ett smidigt språk att börja programmera med. Tack vare att det är tolkat behöver dina skript inte kompileras, vilket innebär att du kan köra dem direkt efter redigering och göra dem körbara. Detta resulterar i en effektiv kodnings-, körnings- och felsökningsprocess.
Många har två huvudinvändningar mot Bash-skript, varav den första är hastighet. Kommandona tolkas, inte körs direkt som i kompilerad kod, vilket gör att de kan upplevas som långsammare. Detta är dock som att klaga på att en traktor inte är lika snabb som en bil; de är anpassade för olika syften.
Å andra sidan finns det två aspekter av hastighet. Du kan ofta skapa ett snabbt skript som kan utföra en specifik uppgift avsevärt snabbare än att utveckla en lösning i ett kompilerat språk, som C.
Den andra kritiken är att Bash-skript använder ett terminalfönster, ett gränssnitt som inte alltid passar alla. Om skriptet bara används av dess skapare kan detta vara mindre viktigt. Detsamma gäller skript för bakgrundsprocesser och batch-jobb, som sällan kräver interaktion.
Men det finns tillfällen då du behöver ett mer intuitivt och modernt gränssnitt än en terminal. De flesta är bekanta med grafiska användargränssnitt (GUI). För att skapa en behaglig användarupplevelse måste du kunna skapa och använda GUI-element från dina skript.
Zenity – verktyg för grafiska gränssnitt i skript
Zenity gör det möjligt att integrera en mängd grafiska gränssnittselement i dina Bash-skript. Det är en kraftfull verktygslåda som ger dina skript en modern känsla och ett välbekant utseende. Läs mer i manualen.
Zenity är förinstallerat i Ubuntu, Fedora och Manjaro-distributioner, då det är en del av GNOME. Om du använder KDE kan du titta på kdialog istället, men zenity fungerar oavsett skrivbordsmiljö.
Artikeln visar hur du skapar olika dialogfönster från kommandoraden, hur du lagrar deras returvärden och användarval i variabler, samt hur du använder dialogfönstren i dina skript.
Vi avslutar med en enkel applikation som använder alla tre typer av dialogfönster.
Kalenderdialogfönster
Ett kalenderdialogfönster låter användaren välja ett datum. För att skapa en sådan ruta med zenity krävs ett enkelt tvåordskommando:
zenity --calendar
Detta kommando visar kalenderdialogfönstret. Den har alla funktioner du förväntar dig av en standarddatumväljare. Du kan byta månad och år, och klicka på en dag för att välja det datumet. Dagens datum är markerat som standard när fönstret öppnas.
Klicka på ”OK” för att stänga dialogfönstret och välja det markerade datumet. Du kan även dubbelklicka på ett datum för att göra samma sak.
Om du inte vill välja ett datum kan du klicka på ”Avbryt”, trycka på ”Esc”-tangenten eller stänga dialogrutan.
I exemplet ovan är 19 augusti 2019 valt. Om användaren klickar på ”OK” stängs kalendern och det valda datumet skrivs ut i terminalen.
Du kan ignorera raden ”GTKDialog mappad utan en övergående förälder. Detta är avskräckt.”
GTK är en förkortning av GIMP Toolkit, den verktygslåda som används för att utveckla GNOME-gränssnitt. Den skapades ursprungligen av upphovspersonerna till GNU Image Manipulation Program (GIMP). GNU står för GNU är inte Unix.
GTK-motorn varnar skaparna av zenity om att de har använt en GTK-komponent på ett sätt som inte är helt standard.
Lagring av datumvärdet
Att skriva ut datumet till terminalen är inte särskilt användbart. Om vi ska anropa kalendern från ett skript måste vi lagra det valda datumet så att vi kan använda det i vårt skript. Vi kan också anpassa kalendern ytterligare.
Följande alternativ används tillsammans med kalendern, var och en med en dubbelstreckad ”–” flagga:
- –text: Anger en textsträng som visas i kalendern. Den ersätter standardtexten ”Välj ett datum nedan”.
- –title: Ställer in titeln för kalenderdialogfönstret.
- –day: Ställer in den dag som är vald när kalendern öppnas.
- –month: Ställer in den månad som är vald när kalendern öppnas.
- –year: Ställer in det år som är valt när kalendern öppnas.
Vi använder variabeln `ChosenDate` för att lagra det datum som returneras från kalendern, och skriver sedan ut detta datum i terminalen med `echo $ChosenDate`.
Även om vi uppnår samma resultat som i föregående exempel, har vi nu det valda datumet lagrat i en variabel. Tidigare skrevs det ut och glömdes bort.
ChosenDate=$(zenity --calendar --text "Välj ett datum" --title "How-To Geek Rota" --day 1 --month 9 --year 2019); echo $ChosenDate
Kalendern visar nu vår text och fönstertitel, och datumet är inställt på vårt valda startdatum snarare än dagens datum.
Vi kan också anpassa formatet på datumsträngen som returneras när ett val görs med alternativet `–date-format` följt av en format specifikation. Detta är en sträng av tokens som definierar data och format som inkluderas i utdata. Tokens är desamma som används med `strftime()` C-språkfunktionen. Det finns ett stort urval av dessa.
Vi använder följande tokens:
- %A: Veckodagens fullständiga namn.
- %d: Dagen i månaden som en siffra.
- %m: Månaden som en siffra.
- %y: Året som två siffror (utan århundrade).
ChosenDate=$(zenity --calendar --text "Välj ett datum" --title "How-To Geek Rota" --date-format="%A %d/%m/%y" --day 1 --month 9 --year 2019); echo $ChosenDate
När ett datum väljs:
returneras datumet med önskat format, visar veckodagen och datumet i europeisk ordning (dag, månad, år).
Dialogfönster för filval: Välja en fil
Filvals-dialogfönster kan vara komplexa, med möjligheten att bläddra i filsystemet, markera filer, välja dem eller avbryta valet.
Zenity erbjuder all denna funktionalitet på ett lika enkelt sätt som kalenderdialogfönstret.
Följande nya alternativ används:
- –file-selection: Berättar för Zenity att vi vill använda ett filvalsdialogfönster.
- –multiple: Tillåter användare att välja mer än en fil.
- –file-filter: Bestämmer vilka filtyper som visas i dialogfönstret.
zenity --file-selection --title "How-To Geek" --multiple --file-filter="*.mm *.png *.page *.sh *.txt"
Filvalsdialogfönstret är lika funktionellt som alla andra filvalsfönster.
Användaren kan navigera genom filsystemet och välja önskade filer.
I exemplet har användaren bläddrat till en ny katalog och valt filen ”button_hybrid.png”.
När användaren klickar på ”OK” stängs filvalsfönstret och filens namn och sökväg skrivs ut i terminalen.
Om du behöver använda filnamnet i någon ytterligare bearbetning kan du lagra det i en variabel, precis som du gjorde med datumet.
Dialogfönster för filval: Spara en fil
Genom att lägga till ett alternativ kan vi förvandla filvalsfönstret till ett filsparningsfönster. Det aktuella alternativet är `–save`. Vi använder också `–confirm-overwrite` för att begära bekräftelse om en fil ska skrivas över.
Response=$(zenity --file-selection --save --confirm-overwrite); echo $Response
Nu visas dialogrutan för filsparning. Observera att det finns ett textfält där användaren kan ange ett filnamn.
Användaren kan navigera till önskad plats i filsystemet och ange ett nytt filnamn, eller välja en befintlig fil att skriva över.
I exemplet har användaren valt en befintlig fil.
När användaren klickar på ”OK” visas ett bekräftelsefönster som frågar om han vill skriva över den valda filen. Filnamnet visas i varningsdialogrutan, vilket ger Zenity sitt professionella utseende.
Om vi inte hade använt alternativet `–confirm-overwrite`, hade filen skrivits över utan bekräftelse.
Filnamnet lagras i variabeln `Response`, som sedan skrivs ut i terminalen.
Meddelandefönster
Med Zenity är det enkelt att inkludera meddelandefönster i dina skript för information, varningar, felmeddelanden och frågor.
Använd följande kommando för att skapa ett felmeddelande:
zenity --error --width 300 --text "Åtkomst nekad. Kan inte skriva till filen."
Följande alternativ används:
- –error: Berättar för Zenity att visa ett felmeddelande.
- –width: Ställer in den initiala bredden på fönstret.
Fönstret visas med den angivna bredden och använder standard GTK-felikonen.
För att skapa ett informationsfönster, använd detta kommando:
zenity --info --width 300 --text "Uppdateringen klar. Klicka på OK för att fortsätta."
Det nya alternativet är `–info`, som används för att skapa informationsfönster.
Följande kommando används för att skapa ett frågefönster:
zenity --question --width 300 --text "Är du säker på att du vill fortsätta?"; echo $?
Det nya alternativet är `–question`, som används för att skapa ett frågefönster.
`$?` är en speciell parameter. Den innehåller returvärdet från den senast exekverade pipeline i förgrunden. Ett nollvärde betyder ”OK”, medan ett annat värde innebär ”Avbryt”.
Du kan tillämpa denna teknik på alla Zenity-dialogfönster för att kontrollera om datan som returneras ska bearbetas eller inte.
I detta fall klickade vi på ”Ja”, så returkoden är noll, vilket betyder ”OK”.
Använd följande kommando för att skapa ett varningsmeddelande:
zenity --warning --title "Lågt hårddiskutrymme" --width 300 --text "Det finns kanske inte tillräckligt med hårddiskutrymme för att spara säkerhetskopian."
Det nya alternativet är `–warning`, som skapar ett varningsmeddelande.
Varningsdialogfönstret visas. Det innehåller ingen fråga, så det har bara en knapp.
Förloppsindikator
Zenity kan användas för att visa en förloppsindikator som visar hur nära skriptet är att slutföras.
Förloppsindikatorn flyttas framåt av värden som skickas in i den från skriptet. För att demonstrera, använd följande kommando:
(for i in $(seq 0 10 100); do echo $i; sleep 1; done)
Kommandot fungerar som följer:
- Kommandot `seq` stegar genom en sekvens från 0 till 100 i steg om 10.
- För varje steg lagras värdet i variabeln `i`, och skrivs ut i terminalen.
- Kommandot `sleep 1` pausar körningen i en sekund.
Vi kan använda detta med Zenitys förloppsindikator genom att överföra resultatet från föregående kommando till zenity:
(for i in $(seq 0 10 100); do echo $i; sleep 1; done) | zenity --progress --title "How-To Geek" --auto-close
Följande nya alternativ används:
- –progress: Berättar för Zenity att visa en förloppsindikator.
- –auto-close: Stänger dialogrutan när förloppsindikatorn når 100 %.
Fönstret visas och förloppsindikatorn flyttar sig mot 100 procent, och pausar en sekund för varje steg.
Vi kan använda konceptet att överföra värden till zenity för att inkludera förloppsindikatorn i ett skript.
Skriv in följande text i en texteditor och spara den som ”progress.sh”:
#!/bin/bash function work-list () { echo "# Första uppgiften" echo "25" sleep 1 echo "# Andra uppgiften" echo "50" sleep 1 echo "# Tredje uppgiften" echo "75" sleep 1 echo "# Sista uppgiften" echo "100" sleep 1 } work-list | zenity --progress --title "How-To Geek" --auto-close exit 0
Här är en sammanfattning av skriptet:
- Skriptet definierar en funktion med namnet `work-list`, där du kan placera dina kommandon och instruktioner. Byt ut `sleep 1`-kommandona mot dina egna.
- Zenity accepterar `echo ”# …”`-rader och visar dem i förloppsindikatorn. Ändra texten på dessa rader för att visa informativa meddelanden för användaren.
- Ekolinjerna som innehåller siffror, t.ex. `echo ”25”` tas också emot av zenity och används för att ställa in värdet på förloppsindikatorn.
- Funktionen `work-list` anropas och överförs till Zenity.
Använd följande kommando för att göra skriptet körbart:
chmod +x progress.sh
Kör skriptet med följande kommando:
./progress.sh
Skriptet körs, textmeddelandet ändras för varje steg i skriptet, och förloppsindikatorn rör sig stegvis mot 100 procent.
Dialogfönster för skalning
Dialogfönstret för skalning låter användare välja ett numeriskt värde genom att flytta ett skjutreglage. Detta förhindrar att användare anger för höga eller låga värden.
Följande nya alternativ används:
- –scale: Berättar för Zenity att ett skalningsfönster ska användas.
- –min-value: Ställer in det lägsta värdet på skalan.
- –max-value: Ställer in det maximala värdet på skalan.
- –step: Bestämmer hur mycket skjutreglaget ska flyttas med piltangenterna. Detta påverkar inte om användaren drar skjutreglaget med musen.
- –value: Ställer in startvärdet och positionen på skjutreglaget.
Kommandot som används:
Response=$(zenity --scale --title "How-To Geek" --text "Välj förstoring." --min-value=0 --max-value=30 --step=3 --value15); echo $Response
Fönstret visas med skjutreglaget inställt på 15.
Användaren kan flytta skjutreglaget för att välja ett annat värde.
När hon klickar på ”OK” överförs värdet till variabeln `Response` och skrivs ut i terminalen.
Dialogfönster för textinmatning
Ett inmatningsfönster låter användaren skriva in text.
Följande nya alternativ används:
- –entry: Berättar för Zenity att ett inmatningsfönster ska användas.
- –entry-text: Du kan använda detta för att visa ett föreslaget värde i textinmatningsfältet. Vi använder ”” för att tvinga fram ett tomt fält, vilket är inte nödvändigt men demonstrerar användningen av alternativet.