Cómo crear cuadros de diálogo GUI en Bash Scripts con Whiptail en Linux

Hace un tiempo, hablamos brevemente sobrezenidad, un programa sencillo que le permite crear cuadros de diálogo gráficos (GTK+) en línea de comandos y scripts de shell. En este artículo, vamos a discutir otra utilidad GUI llamadalátigoque se puede usar para crear cuadros de diálogo GUI en scripts Bash en Linux.

No todos los scripts que escribe necesitan una interfaz gráfica frontal. Pero a veces sería mejor si crea una interfaz gráfica en lugar de depender de la interacción con la línea de comandos. En mi caso, si hay una larga lista de respuestas necesarias en el guión, optaría por una interfaz gráfica.

Whiptail es una utilidad GUI amigable que utiliza untritónbiblioteca de programación. Whiptail ofrece diferentes cuadros de diálogo para diferentes propósitos. Dependiendo de su caso de uso, puede usar estos cuadros de diálogo para hacer que su secuencia de comandos sea más interactiva.

Instalar Whiptail en Linux

Whiptail viene preinstalado con muchas distribuciones, pero si su distribución no tiene Whiptail instalado, siga las instrucciones a continuación para instalarlo.

Para verificar si whiptail ya está instalado, ejecute el siguiente comando.

$ which whiptail

Para instalar Whiptail en Debian/Ubuntu y sus distribuciones derivadas, ejecute el siguiente comando:

$ sudo apt install whiptail -y

Fedora/RHEL/CnetOS/AlmaLinux/Rocky Linux:

$ sudo dnf install newt

Arco Linux, EndeavorOS, Manjaro Linux:

$ sudo pacman -S whiptail

Linux alpino:

$ apk add newt

Opción de ayuda

Puedes usar--helpmarca que mostrará la lista de cuadros de diálogo admitidos y otras opciones que puede usar. En total, hay 10 cuadros de diálogo compatibles con varias funciones y los veremos en las próximas secciones.

$ 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. Cuadro de mensaje

El cuadro de mensaje mostrará mensajes al usuario y esperará hasta que el usuario presione o llave. cuando presionas arrojará uncódigo de retorno 0y si presionas arrojarácódigo de retorno 255.

$ whiptail --title "Welcome Message" --msgbox "Howdy, Welcome to OSTechnix.." 8 78
Caja de mensaje

Vamos a decodificar el comando anterior.

-título Esto agregará título a la ventana.
-msgbox Esto imprimirá el mensaje que proporcione dentro de las comillas.
8 78 Esto establece la altura (8) y el ancho (78) de la ventana.

Puede abrir una nueva terminal y verificar el proceso de cola de látigo. Estará en un estado de suspensión. Significado: está esperando que presione o .

$ 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 

USAR:Estado (S) -> suspensión interrumpible (esperando que se complete un evento).

2. Cuadro de información

La información es similar al cuadro de mensaje, pero la diferencia es que el cuadro de información del cuadro de mensaje no esperará la entrada del usuario. Utilizar–-infoboxmarca y pasa una cadena como argumento que se mostrará en el cuadro de información.

En algunos shells, el cuadro de información se ejecutará pero no mostrará ningún resultado. Tienes que cambiar la emulación de terminal y ejecutarla como lo hice en el siguiente fragmento.

$ TERM=ansi whiptail --title "Welcome Message" --infobox "Howdy, Welcome to OSTechnix.." 8 78 
Caja de información

3. Casilla Sí/No

El cuadro Sí/No mostrará un cuadro de diálogo conoNOopción donde si eliges arrojaráregreso codigo 0y cuando presionas arrojarácódigo de retorno 1.

Usar--yesnobandera para solicitar la elección. Ejecute el siguiente fragmento de código que combina el cuadro sí/no y el cuadro de mensaje. Al principio, mostrará la opción Sí/No y, dependiendo de su elección, arrojará el código de retorno.

Cree un script de shell, copie el siguiente fragmento y ejecútelo.

#!/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 
Cuadro de diálogo Sí/NoCuadro de diálogo Sí/No

Si no tienes idea sobre bash declaraciones condicionales, eche un vistazo a nuestro breve artículo sobre el mismo utilizando el enlace a continuación.

  • Bash Scripting – Declaraciones condicionales

4. Cuadro de texto

El cuadro de texto leerá e imprimirá el archivo. En el siguiente fragmento, estoy leyendo elostechnix.txtexpediente. La bandera –scrolltext le permite usar la rueda del mouse para desplazarse verticalmente cuando tiene páginas largas de texto que no caben en la ventana actual.

$ whiptail --textbox --scrolltext ostechnix.txt 10 80
Caja de textoCaja de texto

5. Redirecciones

Los cuadros de diálogo que verá en la próxima sección requieren que la salida se almacene en una variable y luego se use para el procesamiento. El valor de retorno del widget se envía a stderr en lugar de a stdout. Entonces, debe intercambiar stdout y stderr para que el resultado se almacene en la variable.

Debe usar la siguiente expresión para intercambiar stdout y stderr.

3>&1 1>&2 2>&3

Tratemos de entender la expresión anterior. Sabe que FD1 es la salida estándar y FD2 es el error estándar.

  • 3>&1– Todo lo que se redirige al descriptor de archivo 3 se redirige al descriptor de archivo 1.
  • 1>&2– Todo lo que se envía al descriptor de archivo 1 (Stdout) se redirige al descriptor de archivo 2.
  • 2>&3– Todo lo que se envía al descriptor de archivo 2 (stderr) se redirige al descriptor de archivo 3.

De esta manera, estamos intercambiando stdout y stderr para que la variable pueda almacenar el valor de retorno de los cuadros de diálogo.

6. Cuadro de contraseña

Con el cuadro de diálogo de contraseña, puede escribir contraseñas que no se mostrarán como texto sin formato a medida que las escribe. Utilizar--passwordboxpara solicitar que ingrese la contraseña.

$ whiptail --title "SET PASSWORD" --passwordbox "Choose a strong password"
Cuadro de diálogo de contraseñaCuadro de diálogo de contraseña

cuando presionas arrojará el código de retorno 0 y devolverá la contraseña que ingresó a la consola (stderr) si está ejecutando desde la terminal.

Salida en terminalSalida en terminal

Debe capturar la contraseña en una variable y luego usarla en el script. Como se discutió en la sección Redirección, debe redirigir el resultado.

$ 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"
Almacenar salida en variableAlmacenar salida en variable

7. Cuadro de entrada

El cuadro de diálogo de entrada le pedirá al usuario que proporcione la entrada. Al igual que con el cuadro de diálogo de contraseña, la entrada proporcionada por usted se imprimirá en la terminal si la está ejecutando desde la terminal. Debe usar las redirecciones y almacenar el valor en una variable y luego usarlo para procesar de acuerdo con la lógica de su programa.

NEW_USER=$(whiptail --title "Create New User" --inputbox "Username to be created" 8 40 3>&1 1>&2 2>&3)
Cuadro de entradaCuadro de entrada
Almacenar salida en variableAlmacenar salida en variable

También puede establecer el texto de entrada predeterminado. Todo lo que tiene que hacer es agregar el texto después de la altura y el ancho. A continuación se muestra la sintaxis donde en lugar de[init]colocará el texto predeterminado.

--inputbox <text> <height> <width> [init]

Ejemplo:

whiptail --title "Create New User" --inputbox "Username to be created" 8 40 noname
Texto predeterminadoTexto predeterminado

Ahora combinemos el cuadro de entrada, el cuadro de contraseña, el cuadro Sí/No y el cuadro de texto y escribamos un programa simple de creación de usuarios para ver cómo se pueden acoplar estos cuadros de diálogo.

8. Cuadro de diálogo Lista de verificación

La lista de verificación le permite crear una lista de opciones que un usuario puede seleccionar.

--checklist <text> <height> <width> <listheight> [tag item status]...

Arriba está la sintaxis para crear un cuadro de diálogo de lista de verificación. Tienes que usar el--checklistseguido de la configuración de la altura y el ancho del cuadro de diálogo.

La opción<listheight>especifica cuántas listas vas a crear. Cada lista se etiquetará con<status>que está configurado en ON u OFF. On apunta a lista seleccionada y Off apunta a ninguna selección de lista.

$ 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

Para seleccionar una lista, presione la barra espaciadora y use las flechas hacia arriba y hacia abajo para moverse entre la lista. Una vez hecho esto, presione enter.

Cuadro de diálogo Lista de verificaciónCuadro de diálogo Lista de verificación

Puede almacenar la salida en una matriz y luego usarla. La etiqueta (“Chromepip3, ksnip, virtualbox”) se imprimirán como salida a stderr según la selección.

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

Salida de muestra:

"pip3" "ksnip" "virtualbox"

Si no tienes idea sobre bash arrays, tenemos un artículo detallado sobre bash formación. Te sugiero que le eches un vistazo al siguiente enlace.

  • Bash Scripting: matriz indexada explicada con ejemplos

9. Cuadro de diálogo Lista de radio

El cuadro de diálogo de la lista de radio es similar al cuadro de diálogo de la lista de verificación, pero la única diferencia es que solo puede elegir una opción de la lista. Sintácticamente, tanto la lista de radio como la lista de verificación son lo mismo.

--radiolist <text> <height> <width> <listheight> [tag item status]...

Ejemplo:

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)
Boton de radiobota de radio
$ echo $SELECTED
virtualbox

10. Cuadro de diálogo de menú

El cuadro de diálogo del menú es similar al cuadro de diálogo del botón de opción. La única diferencia que siento es que en el cuadro de diálogo del botón de opción debe presionar para seleccionar un elemento de la lista y luego presionar Intro. Pero en el cuadro de diálogo del menú, todo lo que tiene que hacer es presionar Intro, lo que devolverá el nombre de la etiqueta a stderr.

La sintaxis es similar a la lista de verificación y al botón de opción, pero la única diferencia es que no es necesario activar/desactivar la opción “estado” en el cuadro de diálogo del menú.

--menu <text> <height> <width> <listheight> [tag item]

Ejemplo:

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)
Cuadro de diálogo de menúCuadro de diálogo de menú
$ echo $TO_RUN 
backup

11. Barra de progreso

Para crear una barra de progreso, debe usar la siguiente sintaxis. Primero, pasará un texto que se imprimirá cuando se ejecute la barra de progreso y establecerá la altura y el ancho de la ventana, seguido del porcentaje de progreso.

--gauge <text> <height> <width> <percent>

El porcentaje de progreso será controlado por nuestra lógica. Eche un vistazo al fragmento a continuación. Estoy redirigiendo el bucle while a la barra de progreso e incrementando la variable COUNTER en 10 conteos que se usarán como porcentaje de progreso.

#!/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 de progreso se incrementará en la cuenta de 10.

Cuadro de diálogo de la barra de progresoCuadro de diálogo de la barra de progreso

Conclusión

Hemos llegado al final de este artículo. Aquí, hemos visto brevemente cómo usar Whiptail para crear varios cuadros de diálogo en bash guiones. Si ya has usado la cola de látigo y tienes algún truco debajo de la esclava, compártelo con nosotros a través de la caja de comentarios.

Recurso:

Guías de secuencias de comandos de Bash:

  • Cómo usar el comando de fecha en Bash Scripting en Linux
  • Cómo depurar scripts de Bash en Linux y Unix
  • Bash Scripting: analizar argumentos en Bash Scripts usando getopts
  • Cómo crear cuadros de diálogo GUI en Bash Scripts con Zenity en Linux y Unix
  • Bash Scripting – Declaración de caso
  • Bash Scripting – Declaraciones condicionales
  • Bash Scripting – Manipulación de cadenas
  • Bash Scripting – Comando Printf explicado con ejemplos
  • Bash Scripting: matriz indexada explicada con ejemplos
  • Bash Scripting: matriz asociativa explicada con ejemplos
  • Bash Scripting – Para bucle explicado con ejemplos
  • Secuencias de comandos de Bash: ciclo while y till explicado con ejemplos
  • Redirección de Bash explicada con ejemplos
  • Bash Scripting – Variables explicadas con ejemplos
  • Bash Scripting – Funciones explicadas con ejemplos
  • Comando Bash Echo explicado con ejemplos en Linux
  • Tutorial de Bash Heredoc para principiantes