Qualche tempo fa abbiamo discusso brevemente di Zenity , un semplice programma che consente di creare finestre di dialogo grafiche (GTK+) in script da riga di comando e shell. In questo articolo, parleremo di un'altra utility GUI chiamata Whiptail che può essere utilizzato per creare finestre di dialogo della GUI negli script Bash in Linux.
Non tutti gli script che scrivi richiedono un'interfaccia grafica frontend. Ma a volte sarebbe meglio se crei un'interfaccia grafica invece di fare affidamento sull'interazione con la riga di comando. Nel mio caso, se c'è un lungo elenco di risposte necessarie nello script, sceglierei di utilizzare un'interfaccia grafica.
Whiptail è un'utilità GUI intuitiva che utilizza un newt libreria di programmazione. Whiptail offre diverse finestre di dialogo per scopi diversi. A seconda del tuo caso d'uso, puoi utilizzare queste finestre di dialogo per rendere il tuo script più interattivo.
Installa Whiptail in Linux
Whiptail viene fornito preinstallato con molte distribuzioni, ma se la tua distribuzione non ha Whiptail installato, segui le istruzioni seguenti per installarlo.
Per verificare se Whitail è già installato, esegui il comando seguente.
$ which whiptail
Per installare Whiptail su Debian/Ubuntu e le sue distribuzioni derivate, eseguire il seguente comando:
$ sudo apt install whiptail -y
Fedora/RHEL/CnetOS/AlmaLinux/Rocky Linux:
$ sudo dnf install newt
Arch Linux, EndeavourOS, Manjaro Linux:
$ sudo pacman -S whiptail
Linux alpino:
$ apk add newt
Opzione di aiuto
Puoi usare --help
flag che visualizzerà l'elenco delle finestre di dialogo supportate e altre opzioni che puoi utilizzare. In totale, ci sono 10 finestre di dialogo supportate con varie funzionalità e le esamineremo tutte nelle prossime sezioni.
$ whiptail -help Box options: --msgbox <text> <height> <width> --yesno <text> <height> <width> --infobox <text> <height> <width> --inputbox <text> <height> <width> [init] --passwordbox <text> <height> <width> [init] --textbox <file> <height> <width> --menu <text> <height> <width> <listheight> [tag item] ... --checklist <text> <height> <width> <listheight> [tag item status]... --radiolist <text> <height> <width> <listheight> [tag item status]... --gauge <text> <height> <width> <percent>
1. Finestra di messaggio
La finestra dei messaggi visualizzerà i messaggi all'utente e attenderà che l'utente prema
$ whiptail --title "Welcome Message" --msgbox "Howdy, Welcome to OSTechnix.." 8 78
Decodifichiamo il comando precedente.
--title | Questo aggiungerà il titolo alla finestra |
--msgbox | Questo stamperà il messaggio che fornisci tra le virgolette. |
8 78 | Questo imposta Altezza(8) e Larghezza(78) della finestra. |
Puoi aprire un nuovo terminale e controllare il processo di whistail. Sarà in uno stato di sonno. Significato:sta aspettando che tu prema
$ ps -ef | grep -i whiptail karthick 20023 9251 0 22:41 pts/0 00:00:00 whiptail --title Welcome Message --msgbox Howdy, Welcome to OSTechnix.. 8 78 karthick 20071 19379 0 22:41 pts/1 00:00:00 grep --color=auto -i whiptail
$ ps -q 20023 -o state --no-headers S
NOTA: Stato (S ) -> sospensione interrompibile (in attesa del completamento di un evento).
2. Casella informativa
Le informazioni sono simili alla finestra di messaggio, ma la differenza è diversa dalla casella di informazioni della finestra di messaggio che non attende l'input dell'utente. Usa –-infobox
contrassegnare e passare una stringa come argomento che verrà visualizzato nella casella delle informazioni.
In alcune shell, la casella delle informazioni verrà eseguita ma non visualizzerà alcun risultato. Devi cambiare l'emulazione del terminale ed eseguirla come ho fatto nello snippet qui sotto.
$ TERM=ansi whiptail --title "Welcome Message" --infobox "Howdy, Welcome to OSTechnix.." 8 78
3. Casella Sì/No
Sì/No Box visualizzerà una finestra di dialogo con SÌ o NO opzione dove se scegli genererà ritorno codice 0 e quando premi
Usa --yesno
flag per richiedere la scelta. Esegui il seguente snippet che combina la casella sì/no e la finestra del messaggio. Inizialmente, visualizzerà l'opzione Sì/No e, a seconda della tua scelta, genererà il codice di ritorno.
Crea uno script di shell, copia lo snippet di seguito ed eseguilo.
#!/usr/bin/env bash whiptail --title "CONFIRMATION" --yesno "Should I proceed" 8 78 if [[ $? -eq 0 ]]; then whiptail --title "MESSAGE" --msgbox "Process completed successfully." 8 78 elif [[ $? -eq 1 ]]; then whiptail --title "MESSAGE" --msgbox "Cancelling Process since user pressed <NO>." 8 78 elif [[ $? -eq 255 ]]; then whiptail --title "MESSAGE" --msgbox "User pressed ESC. Exiting the script" 8 78 fi
Se non hai idea delle affermazioni condizionali bash, dai un'occhiata al nostro breve articolo sullo stesso utilizzando il link qui sotto.
- Scripting Bash – Dichiarazioni condizionali
4. Casella di testo
La casella di testo leggerà e stamperà il file. Nello snippet sottostante sto leggendo il ostechnix.txt
file. Il flag –scrolltext ti permette di usare la rotellina del mouse per scorrere verticalmente quando hai lunghe pagine di testo che non rientrano nella finestra corrente.
$ whiptail --textbox --scrolltext ostechnix.txt 10 80
5. Reindirizzamenti
Le finestre di dialogo che vedrai nella sezione successiva richiedono che l'output sia archiviato in una variabile e utilizzato in seguito per l'elaborazione. Il valore restituito dal widget viene inviato a stderr anziché a stdout. Quindi devi scambiare stdout e stderr in modo che il risultato sia memorizzato nella variabile.
Devi usare la seguente espressione per scambiare stdout e stderr.
3>&1 1>&2 2>&3
Proviamo a capire l'espressione di cui sopra. Sai che FD1 è l'uscita standard e FD2 è l'errore standard.
- 3>&1 - Tutto ciò che viene reindirizzato al descrittore di file 3 viene reindirizzato al descrittore di file 1.
- 1>&2 - Tutto ciò che viene inviato al descrittore di file 1(Stdout) viene reindirizzato al descrittore di file 2.
- 2>&3 - Tutto ciò che viene inviato al descrittore di file 2(stderr) viene reindirizzato al descrittore di file 3.
In questo modo stiamo scambiando stdout e stderr in modo che la variabile possa memorizzare il valore restituito dalle finestre di dialogo.
6. Casella password
Utilizzando la finestra di dialogo della password è possibile digitare le password che non verranno visualizzate come testo normale durante la digitazione. Usa --passwordbox
per richiedere l'inserimento della password.
$ whiptail --title "SET PASSWORD" --passwordbox "Choose a strong password"
Quando si preme
È necessario acquisire la password in una variabile, quindi utilizzarla successivamente nello script. Come discusso nella sezione Reindirizzamento devi reindirizzare il risultato.
$ PASSWORD=$(whiptail --title "SET PASSWORD" --passwordbox "Choose a strong password" 8 78 3>&1 1>&2 2>&3) $ echo "The password entered by the user is $PASSWORD"
7. Casella di immissione
La finestra di dialogo Input chiederà all'utente di fornire l'input. Come con la finestra di dialogo della password, l'input da te fornito verrà stampato sul terminale se lo stai eseguendo dal terminale. Devi utilizzare i reindirizzamenti e memorizzare il valore in una variabile, quindi utilizzarlo in seguito per l'elaborazione in base alla logica del tuo programma.
NEW_USER=$(whiptail --title "Create New User" --inputbox "Username to be created" 8 40 3>&1 1>&2 2>&3)
Puoi anche impostare il testo di input predefinito. Tutto quello che devi fare è aggiungere il testo dopo l'altezza e la larghezza. Di seguito è riportata la sintassi dove invece di [init]
posizionerai il testo predefinito.
--inputbox <text> <height> <width> [init]
Esempio:
whiptail --title "Create New User" --inputbox "Username to be created" 8 40 noname
Ora uniamo la casella di input, la casella della password, la casella Sì/No e la casella di testo e scriviamo un semplice programma di creazione utente per vedere come queste finestre di dialogo possono essere accoppiate insieme.
8. Finestra di dialogo Elenco di controllo
Checklist ti consente di creare un elenco di opzioni da cui un utente può selezionare.
--checklist <text> <height> <width> <listheight> [tag item status]...
Sopra è la sintassi per la creazione di una finestra di dialogo elenco di controllo. Devi usare il --checklist
flag seguito dall'impostazione dell'altezza e della larghezza della finestra di dialogo.
L'opzione <listheight>
specifica quante liste creerai. Ogni elenco sarà contrassegnato con <status>
che è impostato su ON o OFF. Attiva punti per elencare selezionati e Disattiva punti per nessuna selezione di elenchi.
$ whiptail --title "SELECT PACKAGES TO INSTALL" --checklist \ "List of packages" 20 100 10 \ "chrome" "browser" OFF \ "pip3" "Python package manager" OFF \ "ksnip" "Screenshot tool" OFF \ "virtualbox" "virtualization software" ON
Per selezionare un elenco, premere la barra spaziatrice e utilizzare le frecce su e giù per spostarsi tra l'elenco. Una volta terminato, premi invio.
È possibile archiviare l'output in un array e utilizzarlo in seguito. I nomi dei tag ("Chrome, pip3, ksnip, virtualbox") verranno stampati come output su stderr in base alla selezione.
SELECTED=($(whiptail --title "SELECT PACKAGES TO INSTALL" --checklist \ "List of packages" 20 100 10 \ "chrome" "browser" OFF \ "pip3" "Python package manager" OFF \ "ksnip" "Screenshot tool" OFF \ "virtualbox" "virtualization software" ON 3>&1 1>&2 2>&3))
$ echo ${SELECTED[@]} # Array of values
Risultato di esempio:
"pip3" "ksnip" "virtualbox"
Se non hai idea degli array bash, abbiamo un articolo dettagliato sull'array bash. Ti suggerisco di dare un'occhiata al link qui sotto.
- Scripting Bash - Array indicizzato spiegato con esempi
9. Finestra di dialogo Elenco radio
La finestra di dialogo dell'elenco delle radio è simile alla finestra di dialogo dell'elenco di controllo, ma l'unica differenza è che puoi scegliere solo un'opzione dall'elenco. Sintatticamente sia la lista delle radio che la lista di controllo sono le stesse.
--radiolist <text> <height> <width> <listheight> [tag item status]...
Esempio:
SELECTED=$(whiptail --title "Choose Only One Package" --radiolist \ "List of packages" 20 100 10 \ "chrome" "browser" OFF \ "pip3" "Python package manager" OFF \ "ksnip" "Screenshot tool" OFF \ "virtualbox" "virtualization software" OFF 3>&1 1>&2 2>&3)
$ echo $SELECTED virtualbox
10. Finestra di dialogo del menu
La finestra di dialogo del menu è simile alla finestra di dialogo del pulsante di opzione. L'unica differenza che sento è che nella finestra di dialogo del pulsante di opzione devi premere
La sintassi è simile all'elenco di controllo e al pulsante di opzione, ma l'unica differenza è che non è necessaria l'opzione "stato" per impostare ON/OFF nella finestra di dialogo del menu.
--menu <text> <height> <width> <listheight> [tag item]
Esempio:
TO_RUN=$(whiptail --title "Menu example" --menu "Choose an option" 25 78 5 \ "backup" "Start taking defined backup" \ "restore" "restore from last backup" \ "Schedule" "Display active backup schedules" 3>&1 1>&2 2>&3)
$ echo $TO_RUN backup
11. Barra di avanzamento
Per creare una barra di avanzamento devi utilizzare la seguente sintassi. Per prima cosa, passerai un testo che verrà stampato quando la barra di avanzamento è in esecuzione e imposterai l'altezza e la larghezza della finestra seguite dalla percentuale di avanzamento.
--gauge <text> <height> <width> <percent>
La percentuale di avanzamento sarà controllata dalla nostra logica. Dai un'occhiata allo snippet qui sotto. Sto reindirizzando il ciclo while alla barra di avanzamento e incrementando la variabile COUNTER in 10 conteggi che verranno utilizzati come percentuale di avanzamento.
#!/usr/bin/env bash COUNTER=0 while [[ ${COUNTER} -le 100 ]]; do sleep 1 COUNTER=$(($COUNTER+10)) echo ${COUNTER} done | whiptail --gauge "Running Data Loader" 6 50 ${COUNTER}
La barra di avanzamento aumenterà nel conteggio di 10.
Conclusione
Siamo giunti alla fine di questo articolo. Qui, abbiamo visto brevemente come usare Whiptail per creare varie finestre di dialogo negli script bash. Se hai già usato Whistail e hai qualche trucco sotto lo schiavo, condividilo con noi attraverso la casella dei commenti.