Whiptail, diálogos para el terminal

Este es uno de los capítulos del tutorial Diálogos para scripts. Encontrarás los enlaces a todos los de capítulos, al final de este artículo.

En este nuevo capítulo del tutorial encontrarás una nueva herramienta para crear diálogos para tus scripts en Bash. De nuevo, esta herramienta es para crear esos diálogos para el terminal, no se trata de una interfaz gráfica. Se trata de whiptail un programa para mostrar cuadros de diálogo en el terminal.

Es posible que te preguntes si realmente necesitas una herramienta como whiptail para crear cuadros de diálogo en el terminal. La cuestión es que una aplicación como esta te puede ser de gran utilidad, para dar una interfaz al usuario mas amigable, aunque sea en el terminal.

¿Y porque no hacer una interfaz gráfica como las que has visto en los últimos episodios del podcast? No siempre es posible. Si te conectas vía ssh a otra máquina, no tendrás esa posibilidad. Por ejemplo, si lo haces a una Raspberry Pi Zero o a cualquier otra máquina de recursos muy limitados, o que simplemente no te den esa posibilidad.

Whiptail, diálogos para el terminal

Whiptail, diálogos para el terminal

Como verás, la sintaxis de esta herramienta es muy similar a dialog, que pudiste ver en el primer capítulo de este tutorial. Se trata de una buena alternativa que debes tener presente para casos de necesidad.

Instalación

whiptail se encuentra en los repositorios oficiales de Ubuntu, con lo que la instalación es tan sencilla, como ejecutar la siguiente instrucción en un terminal,

sudo apt install whiptail

Indicarte que puedes consultar la versión que tienes instalada con simplemente ejecutar un whiptail -v. En mi caso, en el momento de preparar este capítulo del tutorial tenía instalada la versión 0.52.21.

En cuanto a la ayuda, ten en cuenta, que siempre puedes consultarla utilizando la opción whiptail -h o bien las páginas man ejecutando la instrucción man whiptail.

A partir de aquí, ya puedes empezar a crear tus cuadros de diálogo en el terminal, y esto es lo que voy a hacer a continuación, comenzando por ejemplos sencillos para ir complicándolos poco a poco.

Un cuadro de diálogo en el terminal

Empieza por el mas sencillo de los cuadros de diálogo. Se trata de --infobox. Con esta opción simplemente te mostrará un cuadro de diálogo con la información que tu quieras aportar al usuario.

whiptail --title "https://atareao.es" \
         --infobox "Este es el mensaje que se muestra" 7 40

En este ejemplo defines el título con la opción --title y el contenido del cuadro de diálogo. Además tienes que definir el alto y el ancho. Indicarte que en el caso de que las dimensiones no sean suficiente, o bien, no se mostrará parte o nada del contenido. De hecho, en el ejemplo anterior, con un alto inferior a 7 no se muestra nada, y con un ancho inferior a 40 ya empieza a cortarse el contenido.

whiptail un dialogo sencillo

Sin embargo, al menos, en la versión que estoy utilizando, la opción --infobox de whiptail tiene un bug y no funciona en xterm. La opción es establecer la variable TERM a vt220 como en el siguiente ejemplo,

TERM=vt220
whiptail --title "https://atareao.es" \
         --backtitle "Mensaje de fondo" \
         --infobox "Este es el mensaje que se muestra" 7 40

Por otro lado, es posible cambiar la ubicación de la ventana, para que en lugar de que aparezca centrada en el terminal, aparezca en la parte superior izquierda del mismo. Para ello, tienes que utilizar la opción --topleft, como te muestro en el siguiente ejemplo,

TERM=vt220
whiptail --title "https://atareao.es" \
         --backtitle "Mensaje de fondo" \
         --infobox "Este es el mensaje que se muestra" 7 40 \
         --topleft

Esta opción la puedes utilizar también en el resto de cuadros de diálogo que puedes encontrar en los siguientes apartados.

Esperando confirmación del usuario

Si necesitas confirmación por parte del usuario, por ejemplo, la aceptación de una licencia, ese cuadro de diálogo del ejemplo anterior se queda corto. Necesitas al menos un botón. Esto se soluciona con una opción de esta herramienta, --msgbox. Por ejemplo,

whiptail --title "https://atareao.es" \
         --msgbox "Este es el mensaje que se muestra" 7 40
diálogo con confirmación del usuario

Si lo que quieres es mostrar el contenido de un archivo, por ejemplo, de nuevo, la licencia de tu código, deberías plantearte la opción --textbox. En el caso de que este texto sea muy largo, puedes añadir también la opción --scrolltext. Por ejemplo, en el primer caso, podría ser como lo siguiente,

whiptail --title "https://atareao.es" \
         --textbox LICENSE 10 80
Un ejemplo de mostrar una licencia

Sin embargo, dada la extensión del texto, este no se muestra por lo que es necesario utilizar la opción --scrolltext que te permitirá utilizar una barra de desplazamiento para moverte a lo largo de todo el texto, tal y como te muestro en el siguiente ejemplo,

whiptail --title "https://atareao.es" \
         --textbox LICENSE 10 80 \
         --scrolltext
Cuadro de diálogo para mostrar una licencia con barra de desplazamiento

Preguntando al usuario

De nuevo, el cuadro de diálogo anterior se quedará corto, si lo que estás buscando es que el usuario responda una pregunta con un Si o con un No. Pero de nuevo, whiptail, viene a resolverte el problema con una nueva opción, y es que en lugar de utilizar --msgbox puedes utilizar --yesno que hará exactamente lo que estás buscando. Continuando con el ejemplo anterior,

whiptail --title "https://atareao.es" \
         --yesno "¿Quiere continuar?" 7 40
Cuadro de diálogo con pregunta

Sin embargo, si bien, ahora le has dado la oportunidad al usuario que responda a la cuestión que le has planteado, tu no sabes su respuesta. Esto, de nuevo lo puedes resolver fácilmente como por ejemplo te muestro a continuación,

whiptail --title "https://atareao.es" \
         --yesno "¿Quiere continuar?" 7 40
ans=$?
echo $ans
if [ $ans -eq 0 ]
then
    echo "Respondió si"
else
    echo "Respondió no"
fi

¿Como nos indica el usuario su nombre?

Hasta el momento has podido interactuar con el usuario, pero poco. Quiero decir, que al final, solo le has realizado preguntas sencillas, donde el solo tenía que pulsar un botón. Pero ¿como hacer para que el usuario introduzca un texto, por ejemplo su nombre?. En este caso, whiptail tiene otra opción para resolver esta situación, se trata de --inputbox

Para que todo funcione como esperas, es necesario intercambiar stdout y stderr, conforme puedes ver en el siguiente ejemplo,

respuesta=$(whiptail --title "https://atareao.es" \
                     --inputbox "¿Cual es tu nombre?" 7 40 Pepe \
                     3>&1 1>&2 2>&3)
status=$?
if [ $status = 0 ]
then
    echo "Tu nombre es: $respuesta"
else
    echo "No me has querido decir el nombre"
fi
Cuadro de diálogo con whiptail para introducir un nombre

¿Y si lo que necesitas es que introduzca una contraseña? Y cuando te digo una contraseña, te digo cualquier otra información sensible que no quieras que la vean otros usuarios que estén junto al que está tecleando. En este caso, la opción que tienes que utilizar es --passwordbox, eso si, con el mismo truco que en el ejemplo anterior,

respuesta=$(whiptail --title "https://atareao.es" \
                     --passwordbox "Introduce la contraseña:" 7 40 \
                     3>&1 1>&2 2>&3)
status=$?
if [ $status = 0 ]
then
    echo "Tu contraseña es: $respuesta"
else
    echo "No me has querido decir la contraseña"
fi
Cuadro de diálogo con whiptail para introducir una contraseña

¿Como seleccionar una opción?

Otra de los cuadros de diálogos mas habituales que vas a necesitar, es uno en el que le muestres al usuario varias opciones para que elija una, o incluso para que elija varias.

En el caso que quieras que el usuario solo seleccione una de las opciones que le ofreces tienes que utilizar un cuadro de diálogo del tipo --radiolist. En este caso, le puedes indicar que opción está habilitada utilizando ON, y en otro caso OFF.

Por ejemplo, si quieres que tu usuario elija entre varios colores puedes utilizar,

ans=$(whiptail --title "https://atareao.es" \
               --radiolist "Elige un color" 10 80 4 \
               "AZUL" "azul" OFF \
               "ROJO" "rojo" OFF \
               "GRIS" "gris" ON \
               "LILA" "lila" OFF \
               3>&1 1<&2 2>&3)
Cuadro de diálogo para seleccionar una opción

Si por el contrario lo que quieres es que el usuario tenga la posibilidad de seleccionar varios colores, en ese caso, tienes que utilizar un cuadro de diálogo del tipo --checklist. En este caso tienes el mismo formato que en el ejemplo anterior, pero tienes la posibilidad de poner por defecto varios colores seleccionados,

ans=$(whiptail --title "https://atareao.es" \
               --checklist "Elige uno o varios colores" 10 80 4 \
               "AZUL" "azul" OFF \
               "ROJO" "rojo" ON \
               "GRIS" "gris" ON \
               "LILA" "lila" OFF \
               3>&1 1<&2 2>&3)
Cuadro de diálogo para seleccionar varias opciones

Menús

Otra opción de interacción que tienes con el usuario es mediante el uso de menús. Mediante este elemento puedes hacer que el usuario navegue entre diferentes opciones. Por ejemplo, el típico menú para gestionar usuario lo podrías hacer de la siguiente forma,

ans=$(whiptail --title "https://atareao.es" \
               --menu "Elige una opción" 10 80 2 \
               "Añadir" "Añadir un usuario" \
               "Modificar" "Modificar un usuario" \
               "Eliminar" "Eliminar un usuario" \
               "Listar" "Listar los usuarios" \
               3>&1 1<&2 2>&3)
Elemento de menú

Barra de progreso

Otro elemento que te puede resultar de gran utilidad es una barra de progreso. Una barra de progreso, le da información al usuario, no solo de la duración de un determinado progreso, sino también de que el proceso está en marcha. Esto es así, porque de otra manera, el usuario puede pensar que no el proceso se ha detenido, ha terminado o incluso que se ha colgado. En el caso de whiptail tienes el cuadro de diálogo --gauge.

Un ejemplo sencillo de como funcionaría una barra de progreso con whiptail puede ser el siguiente,

{
    for i in {0..100..10};do
        sleep 1
        echo $i
    done
} | whiptail --title "https://atareao.es" \
             --gauge "Espera mientras termino..." 5 40 0
Cuadro de diálogo con whiptail para mostrar una barra de progreso

Conclusión

Como ves, esta herramienta tiene algunas menos opciones, que las que hemos visto en los capítulos anteriores de este tutorial. Sin embargo, es una herramienta que puedes tener en cuenta para cuando la necesites.


Más información,

Imagen de portada de Sigmund en Unsplash

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *