Come aggiungere una GUI agli script della shell di Linux
Pubblicato: 2022-01-29 Puoi utilizzare finestre della GUI, cursori, pulsanti di opzione, barre di avanzamento e altro nei tuoi script Bash. Scopri come utilizzare il toolkit zenity
e rinnova i tuoi script Bash. Ti mostreremo come.
Lo scripting Bash è un potente linguaggio di programmazione e, poiché è integrato nella shell Bash, è prontamente disponibile per tutti. È un linguaggio facile per iniziare a programmare. Poiché è interpretato, non è necessario compilare gli script. Non appena hai modificato il file di script e lo hai reso eseguibile, puoi eseguirlo. Ciò rende il ciclo di codifica, esecuzione e debug abbastanza efficiente.
Ci sono due principali lamentele che le persone hanno con gli script Bash e il primo è la velocità. Poiché la shell Bash interpreta i comandi nello script, non vengono eseguiti rapidamente come il codice compilato. Tuttavia, questo è come lamentarsi del fatto che un trattore non è veloce come un'auto; sono pensati per cose diverse.
Ci sono due tipi di velocità, però. Spesso puoi mettere insieme uno script veloce e usarlo per eseguire un'attività molto più rapidamente rispetto allo sviluppo di una soluzione in un linguaggio compilato, come C.
La seconda lamentela che le persone hanno con gli script Bash è l'interfaccia utente: è una finestra di terminale. Naturalmente, a volte l'interfaccia non ha importanza. Se l'unica persona che utilizzerà mai lo script è il suo autore, l'interfaccia probabilmente non è così importante. Né ha importanza per gli script che eseguono l'elaborazione in background e di tipo batch. In genere, tali script non richiedono molta (se presente) interazione da parte dell'utente.
Ci sono occasioni in cui hai bisogno di qualcosa di un po' più intuitivo e moderno della finestra del terminale. La maggior parte delle persone ha familiarità con un'interfaccia utente grafica (GUI). Per offrire alle persone un'esperienza il più agevole possibile, devi creare e utilizzare elementi della GUI dai tuoi script.
L'applicazione Zenity
zenity
ti consente di incorporare un'ampia gamma di elementi dell'interfaccia grafica nei tuoi script Bash. È un potente toolkit che conferisce ai tuoi script un aspetto moderno e un aspetto contemporaneo e familiare.
zenity
è preinstallato sulle distribuzioni Ubuntu, Fedora e Manjaro. Fa parte di GNOME. Se usi KDE, potresti voler controllare invece kdialog
, sebbene zenity
funzioni su qualsiasi ambiente desktop.
Gli esempi in questo articolo mostrano come creare finestre di dialogo diverse dalla riga di comando, come acquisire i valori restituiti e le selezioni utente nelle variabili e come utilizzare le finestre di dialogo negli script.
Terminiamo con una piccola applicazione che utilizza tutti e tre i tipi di finestre di dialogo.
La finestra di dialogo del calendario
Una finestra di dialogo del calendario consente a qualcuno di selezionare una data. Per crearne uno con zenity
è necessario un unico comando di due parole:
zenity --calendario
Viene visualizzata la finestra di dialogo del calendario. Questo ha tutte le funzionalità che ti aspetteresti da un selettore di date standard. È possibile modificare il mese e l'anno e fare clic su un giorno per selezionare quella data. Per impostazione predefinita, la data odierna viene evidenziata quando viene visualizzata la finestra.
Fare clic su "OK" per chiudere la finestra di dialogo e selezionare la data evidenziata. Fare doppio clic su una data fa la stessa cosa.
Se non desideri selezionare una data, fai clic su "Annulla", premi il tasto "Esc" sulla tastiera o chiudi la finestra di dialogo.
Nell'esempio sopra, è selezionato il 19 agosto 2019. Se l'utente fa clic su "OK", il calendario si chiude e la data selezionata viene stampata nella finestra del terminale.
Puoi ignorare la riga "GTKDialog mappato senza un genitore transitorio. Questo è sconsigliato".
GTK sta per GIMP Tool Kit, che è il toolkit utilizzato per sviluppare l'interfaccia GNOME. È stato originariamente ideato dagli autori del GNU Image Manipulation Program (GIMP). GNU sta per GNU's Not Unix.
Il motore GTK avverte gli autori di zenity
che hanno utilizzato un componente GTK in modo non standard.
Catturare il valore della data
Stampare la data sul terminale non fa molto per noi. Se chiameremo questo calendario da uno dei nostri script, dobbiamo acquisire il valore della data selezionato in modo da poter fare qualcosa di utile con esso nel nostro script. Personalizzeremo leggermente anche il calendario.
Useremo le seguenti opzioni con il calendario. Devono essere tutti utilizzati con il flag “–” con il doppio trattino:
- –text : specifica una stringa di testo da visualizzare nel calendario. Sostituisce l'impostazione predefinita "Seleziona una data dal basso".
- –title : Imposta il titolo della finestra di dialogo del calendario.
- –day : imposta il giorno selezionato all'apertura del calendario.
- –mese : imposta il mese selezionato all'apertura del calendario.
- –year : imposta l'anno selezionato all'apertura del calendario.
Stiamo usando una variabile chiamata ChosenDate
per acquisire la data restituita dal calendario. E stiamo usando echo $ChosenDate
per stampare quella data nella finestra del terminale.
Sì, abbiamo ottenuto lo stesso risultato nell'esempio precedente, ma qui abbiamo la data selezionata memorizzata in una variabile. Nell'esempio precedente, è stato stampato e dimenticato.
ChosenDate=$(zenity -- calendar --text "Scegli una data" --title "How-To Geek Rota" --day 1 -- month 9 --year 2019); echo $ChosenDate
Ora, il calendario mostra il nostro prompt e il titolo della nostra finestra. La data è impostata sulla data di inizio prescelta anziché sulla data odierna.
Possiamo anche personalizzare il formato della stringa di data restituita quando viene effettuata una selezione. L'opzione --date-format
deve essere seguita da un identificatore di formato. Questa è una stringa di token che definisce i dati e i formati da includere nell'output. I token sono gli stessi usati con la funzione del linguaggio C strftime()
e ce n'è una vasta selezione.
I token che stiamo utilizzando sono:
- %A : Il nome completo del giorno della settimana.
- %d : il giorno del mese come cifra.
- %m : il mese come cifra.
- %y : l'anno a due cifre (nessun secolo).
ChosenDate=$(zenity -- calendario --text "Scegli una data" --title "Come fare per Geek Rota" --date-format="%A %d/%m/%y" --day 1 -- mese 9 --anno 2019); echo $ChosenDate
Qualcuno seleziona una data:
E la data viene restituita utilizzando il nostro formato. Mostra il nome del giorno della settimana, seguito dalla data in ordine europeo: giorno, mese, anno.
La finestra di dialogo di selezione del file: scelta di un file
Le finestre di dialogo per la selezione dei file sono piuttosto complesse. Le persone possono sfogliare il file system, evidenziare uno o più file, quindi fare clic su "OK" per selezionare quei file o annullare del tutto la selezione.
zenity
fornisce tutte queste funzionalità e altro ancora. Ed è facile da usare come la finestra di dialogo del calendario.
Le nuove opzioni che useremo sono:
- –file-selection : dice a
zenity
che vogliamo usare una finestra di dialogo per la selezione dei file. - –multiple : consente a qualcuno di selezionare più di un file.
- –file-filter : indica alla finestra di dialogo del file quali tipi di file visualizzare.
zenity --file-selection --tile "How-To Geek" --multiple --file-filter='*.mm *.png *.page *.sh *.txt'
La finestra di dialogo per la selezione dei file è funzionale come qualsiasi altra finestra di selezione dei file.
L'utente può navigare nel file system e selezionare il file di sua scelta.
Abbiamo individuato una nuova directory e selezionato un file chiamato "button_hybrid.png".
Quando si fa clic su "OK", la finestra di dialogo di selezione del file si chiude e il nome del file e il percorso vengono stampati nella finestra del terminale.
Se devi utilizzare il nome del file in qualsiasi ulteriore elaborazione, puoi acquisirlo in una variabile, proprio come hai fatto per la data dal calendario.
La finestra di dialogo di selezione del file: salvataggio di un file
Se aggiungiamo un'opzione, possiamo trasformare la finestra di dialogo per la selezione dei file in una finestra di dialogo per il salvataggio dei file. L'opzione è --save
. Useremo anche l'opzione --confirm-overwrite
. Ciò richiede alla persona di confermare che desidera sovrascrivere un file esistente.
Response=$(zenity --file-selection --save --confirm-overwrite); eco $Risposta
Viene visualizzata la finestra di dialogo di salvataggio del file. Nota che c'è un campo di testo in cui qualcuno può digitare un nome file.
L'utente può accedere alla posizione di sua scelta all'interno del file system, fornire un nome per il file o fare clic su un file esistente per sovrascriverlo.
Nell'esempio sopra, l'utente ha evidenziato un file esistente.
Quando fa clic su "OK", viene visualizzata una finestra di dialogo di conferma che gli chiede di confermare che desidera sostituire il file esistente. Notare che il nome del file viene visualizzato nella finestra di dialogo di avviso. Questo è il tipo di attenzione ai dettagli che conferisce a zenity
il suo aspetto professionale.
Se non avessimo usato l'opzione --confirm-overwrite
, il file sarebbe stato sovrascritto silenziosamente.
Il nome del file è memorizzato nella variabile Response
, che stampa nella finestra del terminale.
Finestre di dialogo di notifica
Con zenity
, l'inclusione di finestre di dialogo di notifica slick nei tuoi script è semplice. Ci sono finestre di dialogo stock a cui puoi fare riferimento per fornire informazioni, avvisi, messaggi di errore e domande per l'utente.
Per creare una finestra di dialogo con un messaggio di errore, utilizzare il comando seguente:
zenity --error --width 300 --text "Autorizzazione negata. Impossibile scrivere sul file."
Le nuove opzioni che stiamo utilizzando sono:
- –error : dice a
zenity
che vogliamo usare una finestra di dialogo di errore. - –width : Imposta la larghezza iniziale della finestra.
La finestra di dialogo di errore viene visualizzata alla larghezza specificata. Utilizza l'icona di errore GTK standard.
Per creare una finestra di dialogo delle informazioni, utilizzare il comando seguente:
zenity --info --width 300 --text "Aggiornamento completato. Fare clic su OK per continuare."
La nuova opzione che stiamo usando è --info
, che dice a zenity
di creare una finestra di dialogo con le informazioni.
Per creare una finestra di dialogo per le domande, utilizzare il comando seguente:
zenity --question --width 300 --text "Sei felice di procedere?"; eco $?
La nuova opzione che stiamo usando è --question
, che dice a zenity
di creare una finestra di dialogo per le domande.
Il $?
è un parametro speciale. Contiene il valore restituito dalla pipeline in primo piano eseguita più di recente. In termini generali, questo è il valore dell'ultimo processo chiuso. Un valore zero significa "OK" e un valore di uno o più significa "Annulla".
Questa è una tecnica generale che puoi applicare a qualsiasi finestra di dialogo di zenity
. Selezionando questo valore nello script, puoi determinare se i dati restituiti da una finestra di dialogo devono essere elaborati o ignorati.
Abbiamo fatto clic su "Sì", quindi il codice di ritorno è uno zero che indica "OK".
Per creare una finestra di dialogo di avviso, utilizzare il comando seguente:
zenity --warning --title "Spazio su disco rigido insufficiente" --width 300 --text "Potrebbe non esserci abbastanza spazio su disco rigido per salvare il backup."
La nuova opzione che stiamo usando è --warning
, che dice a zenity
di creare una finestra di dialogo di avviso.
Viene visualizzata la finestra di dialogo di avviso. Non è una domanda, quindi ha solo un pulsante.
La finestra di dialogo di avanzamento
Puoi utilizzare la finestra di dialogo di avanzamento di zenity
per visualizzare una barra di avanzamento che indica quanto è vicino al completamento del tuo script.
La barra di avanzamento viene avanzata in base ai valori che vengono inviati tramite pipe dal tuo script. Per dimostrare il principio, utilizzare il seguente comando:
(for i in $(seq 0 10 100); do echo $i; dormi 1; fatto)
Il comando si scompone in questo modo:
- Il comando
seq
scorre una sequenza da 0 a 100, a passi di 10. - Ad ogni passaggio, il valore viene memorizzato nella variabile
i
. Questo stampa sulla finestra del terminale. - Il comando si interrompe per un secondo, a causa del comando
sleep 1
.
Possiamo usarlo con la finestra di dialogo di avanzamento di zenity
per dimostrare la barra di avanzamento. Nota che stiamo reindirizzando l'output del comando precedente in zenity:
(for i in $(seq 0 10 100); do echo $i; dormi 1; fatto) | zenity --progress --title "How-To Geek" -- chiusura automatica
Le nuove opzioni che stiamo utilizzando sono:
- –progress : dice a
zenity
che vogliamo usare una finestra di dialogo di avanzamento. - –auto-close : chiude la finestra di dialogo quando la barra di avanzamento raggiunge il 100%.
Viene visualizzata la finestra di dialogo di avanzamento e la barra avanza verso il 100 percento, fermandosi per un secondo tra ogni passaggio.
Possiamo usare quel concetto di piping dei valori in zenity
per includere la finestra di dialogo di avanzamento in uno script.
Inserisci questo testo in un editor e salvalo come "progress.sh".
!/bin/bash funzione lista di lavoro () { echo "# Primo elemento di lavoro" eco "25" dormire 1 echo "# Secondo elemento di lavoro" eco "50" dormire 1 echo "# Terzo elemento di lavoro" eco "75" dormire 1 echo "# Ultimo elemento di lavoro" eco "100" dormire 1 } lista di lavoro | zenity --progress --title "How-To Geek" --auto-close uscita 0
Ecco una ripartizione della sceneggiatura:
- Lo script definisce una funzione chiamata
work-list
. Qui è dove metti i tuoi comandi e le istruzioni per eseguire il lavoro reale. Sostituisci ciascuno dei comandisleep 1
con quelli reali. -
zenity
accetta le righeecho "# ..."
e le visualizza all'interno della finestra di dialogo di avanzamento. Modificare il testo di queste righe, in modo che trasmettano messaggi informativi all'utente. - Anche le linee di
echo
che contengono numeri, comeecho "25"
, sono accettate dazenity
e impostano il valore della barra di avanzamento. - La funzione lista di lavoro viene chiamata e convogliata in
zenity
.
Utilizzare questo comando per rendere eseguibile lo script:
chmod +x progress.sh
Utilizzare questo comando per eseguire lo script:
./progress.sh
Lo script viene eseguito e il messaggio di testo cambia durante l'esecuzione di ciascuna fase dello script. La barra di avanzamento si sposta gradualmente verso il 100 percento.
La finestra di dialogo Scala
La finestra di dialogo della scala consente a qualcuno di spostare un cursore per scegliere un valore numerico. Ciò significa che non può inserire un valore troppo alto o troppo basso.
Le nuove opzioni che stiamo utilizzando sono:
- –scale : dice a
zenity
che vogliamo usare una finestra di dialogo della scala. - –min-value : Imposta il valore minimo per la scala.
- –max-value : Imposta il valore massimo per la scala.
- –step : Imposta la quantità di spostamento del cursore quando vengono utilizzati i tasti freccia. Ciò non influisce sui movimenti del cursore se qualcuno usa il mouse.
- –value : Imposta il valore iniziale e la posizione del cursore.
Questo è il comando che stiamo usando:
Response=$(zenity --scale --title "How-To Geek" --text "Seleziona ingrandimento." --min-value=0 --max-value=30 --step=3 --value15); eco $Risposta
Viene visualizzata la finestra di dialogo del dispositivo di scorrimento con il dispositivo di scorrimento impostato su 15.
L'utente può spostare il cursore per selezionare un nuovo valore.
Quando fa clic su "OK", il valore viene trasferito alla variabile Response
e stampato nella finestra del terminale.
La finestra di dialogo di immissione
La finestra di dialogo di immissione consente a qualcuno di inserire del testo.
Le nuove opzioni che stiamo utilizzando sono:
- –entry : dice a
zenity
che vogliamo usare una finestra di dialogo di immissione. - –entry-text : puoi usarlo se vuoi digitare un valore suggerito nel campo di immissione del testo. Stiamo usando "" per forzare un campo vuoto. Questo non è strettamente necessario, ma volevamo documentare l'opzione.
Il comando completo si presenta così:
Response=$(zenity --entry --text "Inserisci il termine di ricerca" --title "Howe-To Geek" --entry-text=""); eco $Risposta
Viene visualizzata una semplice finestra di dialogo, contenente un campo di immissione di testo.
Qualcuno può digitare e modificare il testo.
Quando fa clic su "OK", il valore digitato viene assegnato alla variabile Risposta. Usiamo echo per stampare il valore della variabile nella finestra del terminale.
Mettere tutto insieme
Mettiamo insieme queste tecniche e creiamo uno script funzionale. Lo script eseguirà una scansione delle informazioni hardware e presenterà i risultati all'utente in una finestra di testo scorrevole. Può scegliere un tipo di scansione lunga o corta.
Per questo script, utilizzeremo tre tipi di finestre di dialogo, due delle quali sono nuove per noi:
- La prima è una finestra di dialogo elenco. Permette a qualcuno di fare una scelta.
- La seconda è una finestra di dialogo di avanzamento che consente all'utente di sapere che sta succedendo qualcosa e dovrebbe aspettare.
- La terza è una finestra di informazioni di testo, che mostra i risultati all'utente.
Inserisci questo testo in un editor e salvalo come "hardware-info.sh".
#!/bin/bash # Visualizza l'elenco dell'hardware per questo computer FileTemp=$(mktemp) ListType=`zenity --width=400 --height=275 --list --radiolist \ --title 'Scansione hardware' \ --text 'Seleziona il tipo di scansione:' \ --colonna 'Seleziona' \ --column 'Tipo di scansione' VERO "Corto" FALSO "Lungo"` se [[ $? -eq 1 ]]; poi # hanno premuto Annulla o hanno chiuso la finestra di dialogo zenity --error --title="Scansione rifiutata" --width=200 \ --text="Scansione hardware saltata" uscita 1 elif [$TipoLista == "Corto"]; poi # hanno selezionato il pulsante di opzione breve Flag="--corto" altro # hanno selezionato il pulsante di opzione lungo Bandiera="" fi # cerca le informazioni sull'hardware con il valore appropriato in $Flag hwinfo $Flag | tee >(zenity --width=200 --height=100 \ --title="Informazioni di raccolta" --progress \ --pulsate --text="Verifica hardware..." \ --auto-kill --auto-close) >${TempFile} # Visualizza le informazioni sull'hardware in una finestra a scorrimento zenity --larghezza=800 --altezza=600 \ --title "Dettagli hardware" \ --text-info --filename="${FileTemp}" uscita 0
Usa questo comando per renderlo eseguibile:
chmod +x hardware-info.sh
Questo script crea un file temporaneo e il nome del file è contenuto nella variabile TempFile:
FileTemp=$(mktemp)
Lo script usa l'opzione --list
per creare una finestra di dialogo zenity
chiamata finestra di dialogo elenco. I caratteri "\" alla fine delle righe indicano allo script di trattarli come una lunga riga avvolta. Ecco il processo:
- Specifichiamo una larghezza e un'altezza per la finestra.
- La finestra di dialogo dell'elenco supporta le colonne. L'opzione
--radiolist
fa sì che la prima colonna sia una colonna di pulsanti di opzione. - Impostiamo un titolo e un prompt di testo per la finestra.
- Impostiamo il titolo della prima colonna su "Seleziona". Il contenuto di questa colonna saranno i pulsanti di opzione.
- Impostiamo il titolo della seconda colonna su "Seleziona" e forniamo il contenuto della seconda colonna. Questa colonna contiene due etichette di testo: "Short" e "Long". Gli indicatori TRUE e FALSE indicano che l'opzione "Short" è selezionata per impostazione predefinita quando viene visualizzata la finestra di dialogo.
- Stiamo archiviando il risultato di questa finestra di dialogo in una variabile denominata
ListType
.
ListType=`zenity --width=400 --height=275 --list --radiolist \ --title 'Scansione hardware' \ --text 'Seleziona il tipo di scansione:' \ --colonna 'Seleziona' \ --column 'Tipo di scansione' VERO "Corto" FALSO "Lungo"`
Se l'utente preme "Annulla", non è necessario controllare il valore in ListType,
possiamo semplicemente uscire. Se preme "OK", dobbiamo scoprire se ha selezionato il pulsante di opzione "Short" o "Long":
- Il parametro speciale
$?
è uguale a zero se l'utente ha premuto "OK". È uguale a uno se ha premuto "Annulla" o ha chiuso la finestra. - Se è uguale a uno, lo script visualizza una finestra di dialogo con le informazioni sull'errore ed esce. Se preme "OK", si passa a testare il valore nella variabile
ListType
. - Se la variabile
ListType
contiene il valore "Short", lo script imposta una variabile denominataFlag
in modo che sia uguale a "–short". - Se la variabile
ListType
non contiene il valore "Short", deve contenere il valore "Long". Lo script imposta una variabile chiamataFlag
su "", che è una stringa vuota. - Lo script utilizza la variabile
Flag
nella sezione successiva.
se [[ $? -eq 1 ]]; poi # hanno premuto Annulla o hanno chiuso la finestra di dialogo zenity --error --title="Scansione rifiutata" --width=200 \ --text="Scansione hardware saltata" uscita 1 elif [$TipoLista == "Corto"]; poi # hanno selezionato il pulsante di opzione breve Flag="--corto" altro # hanno selezionato il pulsante di opzione lungo Bandiera="" fi
Ora che lo script sa quale tipo di scansione desidera l'utente, possiamo eseguire la scansione delle informazioni hardware:
- Lo script chiama il comando
hwinfo
e gli passa il valore nella variabileFlag
. - Se
Flag
contiene "–short", il comandohwinfo
esegue una scansione breve. Se il valore diFlag
è "", nulla passa ahwinfo
e viene eseguita una scansione lunga predefinita. - Lo script convoglia l'output da
hwinfo
intee
.tee
invia l'output azenity
e alTempFile
. - Lo script crea una finestra di dialogo con la barra di avanzamento. Imposta la larghezza e l'altezza della finestra di dialogo, il titolo e i testi dei prompt.
- Lo script non può sapere in anticipo quante informazioni produrrà il comando
hwinfo
, quindi non può impostare la barra di avanzamento in modo che avanzi correttamente al 100%. L'opzione--pulsate
fa sì che la finestra di dialogo di avanzamento visualizzi un indicatore mobile. Questo informa l'utente che sta succedendo qualcosa e dovrebbe aspettare. - L'opzione
--auto-kill
termina lo script se qualcuno fa clic su "Annulla". - L'opzione
--auto-close
fa sì che la finestra di dialogo di avanzamento si chiuda automaticamente al termine del processo che sta monitorando.
# cerca le informazioni sull'hardware con il valore appropriato in $Flag hwinfo $Flag | tee >(zenity --width=200 --height=100 \ --title="Informazioni di raccolta" --progress \ --pulsate --text="Verifica hardware..." \ --auto-kill --auto-close) >${TempFile}
Al termine della scansione di hwinfo
, lo script chiama zenity
per creare una finestra di dialogo con le informazioni di testo con l'opzione --text-info
. La finestra di dialogo delle informazioni di testo mostra il contenuto del file TempFile
:
- Lo script imposta la larghezza e l'altezza della finestra di dialogo e il testo del titolo.
- L'opzione
--flename
viene utilizzata per leggere il contenuto del file contenuto nella variabileTempFIle
.
# Visualizza le informazioni sull'hardware in una finestra a scorrimento zenity --larghezza=800 --altezza=600 \ --title "Dettagli hardware" \ --text-info --filename="${FileTemp}"
Quando l'utente chiude la finestra di dialogo delle informazioni di testo, lo script si chiude.
uscita 0
Accendiamolo e diamo un'occhiata.
./hardware-info.sh
Viene visualizzata la casella di riepilogo. L'opzione "Short" è selezionata per impostazione predefinita.
Selezioniamo "Lungo", quindi fare clic su "OK".
Viene visualizzata la finestra di avanzamento con un indicatore scorrevole. Rimane sullo schermo fino al completamento della scansione dell'hardware.
Al termine della scansione dell'hardware, viene visualizzata la finestra di dialogo delle informazioni di testo con i dettagli della scansione.
Fare clic su "OK".
Anche un irriducibile fantino da riga di comando deve ammettere che un paio di finestre di dialogo della GUI possono dare un tocco professionale a un umile script Bash.