Hvordan legge til en GUI til Linux Shell Scripts

Du kan bruke GUI-vinduer, skyveknapper, alternativknapper, fremdriftslinjer og mer i Bash-skriptene dine. Lær hvordan du bruker Zenity-verktøysettet og gi Bash-manusene dine en ansiktsløftning. Vi viser deg hvordan.

Bash-skripting er et kraftig programmeringsspråk, og fordi det er innebygd i Bash-skallet, er det lett tilgjengelig for alle. Det er et enkelt språk å begynne å programmere i. Fordi det er tolket, trenger du ikke å kompilere skriptene dine. Så snart du har redigert skriptfilen og gjort den kjørbar, kan du kjøre den. Dette gjør syklusen for koding, kjøring og feilsøking ganske effektiv.

Det er to hovedklager folk har med Bash-manus, og den første er hastighet. Fordi Bash-skallet tolker kommandoene i skriptet, utføres de ikke like raskt som kompilert kode. Dette er imidlertid som å klage over at en traktor ikke er like rask som en bil; de er ment for forskjellige ting.

Det er imidlertid to typer hastighet. Du kan ofte slå sammen et raskt skript og bruke det til å utføre en oppgave mye raskere enn å utvikle en løsning i en kompilert språk, for eksempel C.

Den andre klagen folk har med Bash-skript er brukergrensesnittet – det er et terminalvindu. Noen ganger spiller selvfølgelig grensesnittet ingen rolle. Hvis den eneste personen som noen gang vil bruke skriptet er forfatteren, er grensesnittet sannsynligvis ikke så viktig. Det spiller heller ingen rolle for skript som utfører bakgrunns- og batchtypebehandling. Vanligvis trenger ikke slike skript mye (om noen) brukerinteraksjon.

Det er anledninger når du trenger noe litt mer intuitivt og moderne enn terminalvinduet. De fleste er kjent med a grafisk brukergrensesnitt (GUI). For å gi folk en opplevelse som er så friksjonsfri som mulig, må du lage og bruke GUI-elementer fra skriptene dine.

Zenity-applikasjonen

zenity lar deg inkorporere et bredt spekter av grafiske grensesnittelementer i Bash-skriptene dine. Det er en kraftig verktøykasse som gir manusene dine et moderne preg og et moderne, kjent utseende.

zenity er forhåndsinstallert på Ubuntu-, Fedora- og Manjaro-distribusjoner. Det er en del av GNOME. Hvis du bruker KDE, vil du kanskje sjekke ut kdialog i stedet, selv om zenity kjører på et hvilket som helst skrivebordsmiljø.

Eksemplene i denne artikkelen viser deg hvordan du lager de forskjellige dialogvinduene fra kommandolinjen, hvordan du fanger opp returverdiene og brukervalgene i variabler, og hvordan du bruker dialogvinduene i skript.

Vi avslutter med en liten applikasjon som benytter seg av alle tre typer dialogvinduer.

Kalenderdialogvinduet

Et kalenderdialogvindu lar noen velge en dato. For å lage en med zenity krever en enkelt kommando av to ord:

zenity --calendar

Kalenderdialogvinduet vises. Denne har all funksjonaliteten du forventer av en standard datovelger. Du kan endre måned og år, og klikk på en dag for å velge den datoen. Som standard er dagens dato uthevet når vinduet vises.

Klikk «OK» for å lukke dialogvinduet og velg den uthevede datoen. Dobbeltklikk på en dato gjør det samme.

Hvis du ikke ønsker å velge dato, klikker du på «Avbryt», trykker på «Esc»-tasten på tastaturet eller lukker dialogvinduet.

I eksemplet ovenfor er 19. august 2019 valgt. Hvis brukeren klikker «OK», lukkes kalenderen, og den valgte datoen skrives ut i terminalvinduet.

Du kan ignorere linjen, «GTKDialog kartlagt uten en forbigående forelder. Dette er motet.»

GTK står for GIMP-verktøysettsom er verktøysettet som brukes til å utvikle GNOME grensesnitt. Det ble opprinnelig utviklet av forfatterne av GNU Image Manipulation Program (GIMP). GNU står for GNU er ikke Unix.

GTK-motoren advarer forfatterne av Zenity om at de har brukt en GTK-komponent på en ikke-standard måte.

Fange datoverdien

Å skrive ut datoen til terminalen gjør ikke så mye for oss. Hvis vi skal kalle denne kalenderen fra et av skriptene våre, må vi fange opp den valgte datoverdien slik at vi kan gjøre noe nyttig med den i skriptet vårt. Vi vil også tilpasse kalenderen litt.

Vi bruker følgende alternativer med kalenderen. De må alle brukes med det doble «–»-flagget:

–tekst: Spesifiserer en tekststreng som skal vises i kalenderen. Den erstatter standarden «Velg en dato nedenfra.»
–title: Angir tittelen på kalenderdialogvinduet.
–dag: Angir dagen som er valgt når kalenderen åpnes.
–måned: Angir måneden som velges når kalenderen åpnes.
–år: Angir året som velges når kalenderen åpnes.

Vi bruker en variabel kalt ChosenDate for å fange opp datoen som returneres fra kalenderen. Og vi bruker echo $ChosenDate for å skrive ut den datoen til terminalvinduet.

Ja, vi oppnådde samme resultat i forrige eksempel, men her har vi den valgte datoen lagret i en variabel. I forrige eksempel ble det skrevet ut og glemt.

ChosenDate=$(zenity -- calendar --text "Choose a date" --title "How-To Geek Rota" --day 1 -- month 9 --year 2019); echo $ChosenDate

Nå viser kalenderen vår ledetekst og vinduets tittel. Datoen er satt til vår valgte startdato i stedet for dagens dato.

  Slik spiller du inn Linux-skrivebordet ditt med Kooha

Vi kan også tilpasse formatet til datostrengen som returneres når et valg er gjort. Alternativet –date-format må etterfølges av en formatspesifikasjon. Dette er en streng med tokens som definerer dataene og formatene som skal inkluderes i utdataene. Tokenene er de samme som brukes med strftime() C språkfunksjon og det er et stort utvalg av dem.

Tokenene vi bruker er:

%A: Det fulle navnet på ukedagen.
%d: Dagen i måneden som et siffer.
%m: Måneden som et siffer.
%y: Året som to sifre (ingen århundre).

ChosenDate=$(zenity -- calendar --text "Choose a date" --title "How-To Geek Rota" --date-format="%A %d/%m/%y" --day 1 -- month 9 --year 2019); echo $ChosenDate

Noen velger en dato:

Og datoen returneres i vårt format. Den viser navnet på ukedagen, etterfulgt av datoen i europeisk rekkefølge: dag, måned, år.

Dialogvinduet for filvalg: Velge en fil

Dialogvinduer for filvalg er ganske komplekse. Folk kan bla gjennom filsystemet, markere en eller flere filer, og deretter klikke på «OK» for å velge disse filene eller avbryte valget helt.

zenity gir all denne funksjonaliteten, og mer. Og det er like enkelt å bruke som kalenderdialogvinduet.

De nye alternativene vi skal bruke er:

–filvalg: Forteller zenity at vi ønsker å bruke et filvalgsdialogvindu.
–multiple: Lar noen velge mer enn én fil.
–fil-filter: Forteller fildialogvinduet hvilke filtyper som skal vises.

zenity --file-selection --tile "How-To Geek" --multiple --file-filter="*.mm *.png *.page *.sh *.txt"

Dialogvinduet for filvalg er like funksjonelt som et hvilket som helst annet filvalgsvindu.

Brukeren kan bla gjennom filsystemet og velge filen etter eget valg.

Vi har bladd til en ny katalog og valgt en fil kalt «button_hybrid.png.»

Når du klikker «OK», lukkes vinduet for filvalg, og filnavnet og banen skrives ut i terminalvinduet.

Hvis du trenger å bruke filnavnet i ytterligere behandling, kan du fange det i en variabel, akkurat som du gjorde for datoen fra kalenderen.

Dialogvinduet for filvalg: Lagre en fil

Hvis vi legger til ett alternativ, kan vi gjøre filvalgsdialogvinduet til et fillagringsdialogvindu. Alternativet er -lagre. Vi kommer også til å bruke –bekreft-overskriv-alternativet. Dette ber personen om å bekrefte at han ønsker å overskrive en eksisterende fil.

Response=$(zenity --file-selection --save --confirm-overwrite); echo $Response

Fillagringsdialogvinduet vises. Merk at det er et tekstfelt der noen kan skrive inn et filnavn.

Brukeren kan bla til ønsket plassering i filsystemet, gi et navn for filen eller klikke på en eksisterende fil for å overskrive den.

I eksemplet ovenfor uthevet brukeren en eksisterende fil.

Når han klikker «OK», vises et bekreftelsesvindu som ber ham bekrefte at han vil erstatte den eksisterende filen. Merk at navnet på filen vises i advarselsdialogen. Det er den typen oppmerksomhet på detaljer som gir zenity sitt profesjonelle utseende.

Hvis vi ikke hadde brukt alternativet –confirm-overwrite, ville filen blitt overskrevet i det stille.

Navnet på filen lagres i variabelen Response, som skrives ut til terminalvinduet.

Varslingsdialog Windows

Med zenity er det enkelt å inkludere glatte varslingsdialogvinduer i skriptene dine. Det er lagerdialogvinduer du kan ringe til for å gi informasjon, advarsler, feilmeldinger og spørsmål til brukeren.

For å lage et feilmeldingsdialogvindu, bruk følgende kommando:

zenity --error --width 300 --text "Permission denied. Cannot write to the file."

De nye alternativene vi bruker er:

–error: Forteller zenity at vi vil bruke et feildialogvindu.
–bredde: Angir den opprinnelige bredden på vinduet.

Feildialogvinduet vises med den angitte bredden. Den bruker standard GTK-feilikonet.

For å opprette et informasjonsdialogvindu, bruk følgende kommando:

zenity --info --width 300 --text "Update complete. Click OK to continue."

Det nye alternativet vi bruker er –info , som forteller zenity å lage et informasjonsdialogvindu.

For å lage et spørsmålsdialogvindu, bruk følgende kommando:

zenity --question --width 300 --text "Are you happy to proceed?"; echo $?

Det nye alternativet vi bruker er –question, som forteller Zenity å lage et spørsmålsdialogvindu.

$? er en spesiell parameter. Den inneholder returverdien fra den sist utførte forgrunnsrørledningen. Generelt sett er dette verdien fra den sist avsluttede prosessen. En nullverdi betyr «OK», og en verdi på én eller flere betyr «Avbryt».

Dette er en generell teknikk du kan bruke på alle zenity-dialogvinduene. Ved å sjekke denne verdien i skriptet ditt, kan du bestemme om dataene som returneres fra et dialogvindu skal behandles eller ignoreres.

Vi klikket «Ja», så returkoden er en null som indikerer «OK.»

For å opprette et advarselsdialogvindu, bruk følgende kommando:

zenity --warning --title "Low Hard Drive Space" --width 300 --text "There may not be enough hard drive space to save the backup."

Det nye alternativet vi bruker er –warning , som forteller Zenity å lage et advarselsdialogvindu.

  Hvordan spille PlanetSide 2 på Linux

Advarselsdialogvinduet vises. Det er ikke et spørsmål, så den har bare én knapp.

Fremdriftsdialogvinduet

Du kan bruke fremdriftsdialogvinduet for zenity for å vise en fremdriftslinje som indikerer hvor nærme fullføringen av skriptet ditt er.

Fremdriftslinjen er avansert i henhold til verdiene som sendes inn i den fra skriptet ditt. For å demonstrere prinsippet, bruk følgende kommando:

(for i in $(seq 0 10 100); do echo $i; sleep 1; done)

Kommandoen brytes ned slik:

Seq-kommandoen går gjennom en sekvens fra 0 til 100, i trinn på 10.
Ved hvert trinn lagres verdien i variabelen i. Dette skrives ut til terminalvinduet.
Kommandoen stopper i ett sekund på grunn av dvale 1-kommandoen.

Vi kan bruke dette med fremdriftsdialogvinduet for Zenity for å demonstrere fremdriftslinjen. Merk at vi overfører utdataene fra den forrige kommandoen til zenity:

(for i in $(seq 0 10 100); do echo $i; sleep 1; done) | zenity --progress --title "How-To Geek" -- auto-close

De nye alternativene vi bruker er:

–progress: Forteller zenity at vi ønsker å bruke et fremdriftsdialogvindu.
–auto-lukk: Lukker dialogen når fremdriftslinjen når 100 prosent.

Fremdriftsdialogvinduet vises, og linjen beveger seg mot 100 prosent, og stopper i ett sekund mellom hvert trinn.

Vi kan bruke konseptet med å overføre verdier til zenity for å inkludere fremdriftsdialogvinduet i et skript.

Skriv inn denne teksten i en editor og lagre den som «progress.sh.»

!/bin/bash

function work-list () {

echo "# First work item" 
echo "25"
sleep 1

echo "# Second work item" 
echo "50"
sleep 1

echo "# Third work item" 
echo "75"
sleep 1

echo "# Last work item" 
echo "100"
sleep 1

}

work-list | zenity --progress --title "How-To Geek" --auto-close

exit 0

Her er en oversikt over manuset:

Skriptet definerer en funksjon kalt work-list. Det er her du legger kommandoene og instruksjonene dine for å utføre ekte arbeid. Bytt ut hver av sleep 1-kommandoene med dine ekte.
zenity aksepterer ekko «# …»-linjer og viser dem i fremdriftsdialogvinduet. Endre teksten på disse linjene, slik at de sender informative meldinger til brukeren.
Ekkolinjene som inneholder tall, for eksempel ekko «25» , aksepteres også av zenity og setter verdien på fremdriftslinjen.
Arbeidslistefunksjonen kalles og overføres til zenity.

Bruk denne kommandoen for å gjøre skriptet kjørbart:

chmod +x progress.sh

Bruk denne kommandoen til å kjøre skriptet:

./progress.sh

Skriptet kjører, og tekstmeldingen endres etter hvert som hver fase av skriptet kjøres. Fremdriftslinjen beveger seg i trinn mot 100 prosent.

Skala-dialogvinduet

Skaleringsdialogvinduet lar noen flytte en glidebryter for å velge en numerisk verdi. Dette betyr at hun ikke kan legge inn en verdi som er for høy eller lav.

De nye alternativene vi bruker er:

–scale: Forteller zenity at vi vil bruke et skaleringsdialogvindu.
–min-verdi: Angir minimumsverdien for skalaen.
–max-value: Angir maksimalverdien for skalaen.
–trinn: Angir hvor mye glidebryteren beveger seg inn når piltastene brukes. Dette påvirker ikke glidebryterens bevegelser hvis noen bruker musen.
–verdi: Angir startverdien og posisjonen til glidebryteren.

Dette er kommandoen vi bruker:

Response=$(zenity --scale --title "How-To Geek" --text "Select magnification." --min-value=0 --max-value=30 --step=3 --value15); echo $Response

Gliderdialogvinduet vises med glidebryteren satt til 15.

Brukeren kan flytte glidebryteren for å velge en ny verdi.

Når hun klikker «OK», overføres verdien til variabelen Response og skrives ut til terminalvinduet.

Inngangsdialogvinduet

Inntastingsdialogvinduet lar noen legge inn tekst.

De nye alternativene vi bruker er:

–entry: Forteller zenity at vi ønsker å bruke et inngangsdialogvindu.
–entry-text: Du kan bruke denne hvis du vil skrive en foreslått verdi i tekstinntastingsfeltet. Vi bruker «» for å tvinge et tomt felt. Dette er ikke strengt nødvendig, men vi ønsket å dokumentere alternativet.

Den fullstendige kommandoen ser slik ut:

Response=$(zenity --entry --text "Enter your search term" --title "Howe-To Geek" --entry-text=""); echo $Response

Et enkelt dialogvindu vises som inneholder et tekstfelt.

Noen kan skrive og redigere tekst.

Når han klikker «OK», tildeles verdien han skrev til variabelen Respons. Vi bruker ekko for å skrive ut verdien til variabelen i terminalvinduet.

Sette alt sammen

La oss sette disse teknikkene sammen og lage et funksjonelt manus. Skriptet vil utføre en maskinvareinformasjonsskanning og presentere resultatene for brukeren i et rulletekstvindu. Hun kan velge en lang eller kort skanningstype.

For dette skriptet bruker vi tre typer dialogvinduer, hvorav to er nye for oss:

Den første er et listedialogvindu. Det lar noen ta et valg.
Det andre er et fremdriftsdialogvindu som lar brukeren vite at noe skjer, og hun bør vente.
Det tredje er et tekstinformasjonsvindu som viser resultatene til brukeren.

Skriv inn denne teksten i et redigeringsprogram og lagre den som «hardware-info.sh.»

#!/bin/bash

# Display hardware listing for this computer

TempFile=$(mktemp)

ListType=`zenity --width=400 --height=275 --list --radiolist 
     --title 'Hardware Scan' 
     --text 'Select the scan type:' 
     --column 'Select' 
     --column 'Scan Type' TRUE "Short" FALSE "Long"`

if [[ $? -eq 1 ]]; then

  # they pressed Cancel or closed the dialog window 
  zenity --error --title="Scan Declined" --width=200 
       --text="Hardware scan skipped"
  exit 1
 
elif [ $ListType == "Short" ]; then

  # they selected the short radio button 
  Flag="--short"
 
else

  # they selected the long radio button 
  Flag="" 
fi

# search for hardware info with the appropriate value in $Flag
hwinfo $Flag | tee >(zenity --width=200 --height=100 
     --title="Collating Information" --progress 
     --pulsate --text="Checking hardware..." 
     --auto-kill --auto-close) >${TempFile}
 
# Display the hardware info in a scrolling window
zenity --width=800 --height=600 
     --title "Hardware Details" 
     --text-info --filename="${TempFile}"
 
exit 0

Bruk denne kommandoen for å gjøre den kjørbar:

chmod +x hardware-info.sh

Dette skriptet oppretter en midlertidig fil, og navnet på filen holdes i TempFile-variabelen:

TempFile=$(mktemp)

Skriptet bruker –list-alternativet for å lage et zenity-dialogvindu kalt et listedialogvindu. «»-tegnene på slutten av linjene forteller manuset å behandle dem som en lang linje som er pakket rundt. Her er prosessen:

  Last Light Redux på Linux

Vi angir en bredde og høyde for vinduet.
Listedialogvinduet støtter kolonner. Alternativet –radiolist gjør at den første kolonnen er en kolonne med alternativknapper.
Vi angir en tittel og tekstmelding for vinduet.
Vi setter tittelen på den første kolonnen til «Velg». Innholdet i denne kolonnen vil være alternativknappene.
Vi setter tittelen på den andre kolonnen til «Velg», og vi gir innholdet i den andre kolonnen. Denne kolonnen har to tekstetiketter: «Kort» og «Lang». TRUE og FALSE-indikatorene betyr at «Kort»-alternativet er valgt som standard når dialogvinduet vises.
Vi lagrer resultatet fra dette dialogvinduet i en variabel kalt ListType.

ListType=`zenity --width=400 --height=275 --list --radiolist  
     --title 'Hardware Scan'  
     --text 'Select the scan type:'  
     --column 'Select'  
     --column 'Scan Type' TRUE "Short" FALSE "Long"`

Hvis brukeren trykker «Avbryt», trenger vi ikke å sjekke verdien i ListType, vi kan ganske enkelt avslutte. Hvis han trykker «OK», må vi finne ut om han valgte «Kort» eller «Lang» alternativknapp:

Den spesielle parameteren $? er lik null hvis brukeren trykket «OK». Det tilsvarer én hvis han trykket «Avbryt» eller lukket vinduet.
Hvis det tilsvarer én, viser skriptet et dialogvindu med feilinformasjon og avsluttes. Hvis han trykker «OK», går vi videre for å teste verdien i ListType-variabelen.
Hvis ListType-variabelen har verdien «Short», setter skriptet en variabel kalt Flag til lik «–short».
Hvis ListType-variabelen ikke har verdien «Short», må den holde verdien «Long». Skriptet setter en variabel kalt Flag til lik «», som er en tom streng.
Skriptet bruker Flag-variabelen i neste seksjon.

if [[ $? -eq 1 ]]; then 

  # they pressed Cancel or closed the dialog window 
  zenity --error --title="Scan Declined" --width=200  --text="Hardware scan skipped" 
  exit 1 

elif [ $ListType == "Short" ]; then 

 # they selected the short radio button 
 Flag="--short" 

else 

 # they selected the long radio button 
 Flag="" 
fi

Nå som skriptet vet hvilken type skanning brukeren vil ha, kan vi utføre skanningen av maskinvareinformasjon:

Skriptet kaller kommandoen hwinfo og gir den verdien i Flag-variabelen.
Hvis Flag inneholder «–short», utfører hwinfo-kommandoen en kort skanning. Hvis verdien av Flag er «», overføres ingenting til hwinfo og en standard lang skanning utføres.
Skriptet overfører utdataene fra hwinfo til tee. tee sender utdataene til Zenity og TempFile.
Skriptet oppretter et fremdriftslinjedialogvindu. Den angir bredden og høyden på dialogvinduet, og tittelen og ledetekstene.
Skriptet kan ikke vite på forhånd hvor mye informasjon hwinfo-kommandoen vil produsere, så det kan ikke sette fremdriftslinjen til å gå riktig frem til 100 prosent. Alternativet –pulsate får fremdriftsdialogen til å vise en bevegelig indikator. Dette informerer brukeren om at noe skjer og han bør vente.
Alternativet –auto-kill avslutter skriptet hvis noen klikker «Avbryt».
Alternativet –auto-lukk gjør at fremdriftsdialogen lukkes automatisk når prosessen den overvåker fullføres.

# search for hardware info with the appropriate value in $Flag
hwinfo $Flag | tee >(zenity --width=200 --height=100 
     --title="Collating Information" --progress 
     --pulsate --text="Checking hardware..." 
     --auto-kill --auto-close) >${TempFile}

Når hwinfo-skanningen er fullført, kaller skriptet Zenity for å lage et tekstinformasjonsdialogvindu med –text-info-alternativet. Tekstinformasjonsdialogvinduet viser innholdet i TempFile-filen:

Skriptet angir bredden og høyden på dialogvinduet og tittelteksten.
Alternativet –flename brukes til å lese innholdet i filen i TempFIle-variabelen.

# Display the hardware info in a scrolling window 
zenity --width=800 --height=600  
     --title "Hardware Details"  
     --text-info --filename="${TempFile}"

Når brukeren lukker tekstinformasjonsdialogvinduet, avsluttes skriptet.

exit 0

La oss fyre opp og ta en titt.

./hardware-info.sh

Listeboksen vises. Alternativet «Kort» er valgt som standard.

Liste dialogboksen med

La oss velge «Lang» og klikk deretter «OK».

Liste dialogboksen med

Fremdriftsvinduet vises med en glidende indikator. Den forblir på skjermen til maskinvareskanningen er fullført.

Når maskinvareskanningen er fullført, vises tekstinformasjonsdialogvinduet med detaljer fra skanningen.

Klikk «OK.»

Selv en hardhendt kommandolinjejockey må innrømme at et par GUI-dialogvinduer kan gi et ydmykt Bash-skript et profesjonelt preg.