Whiptail, diálogos para el terminal
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
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://www.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.
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://www.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://www.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://www.atareao.es" \
--msgbox "Este es el mensaje que se muestra" 7 40
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://www.atareao.es" \
--textbox LICENSE 10 80
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://www.atareao.es" \
--textbox LICENSE 10 80 \
--scrolltext
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://www.atareao.es" \
--yesno "¿Quiere continuar?" 7 40
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://www.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://www.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
¿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://www.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
¿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://www.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)
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://www.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)
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://www.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)
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://www.atareao.es" \
--gauge "Espera mientras termino..." 5 40 0
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
La entrada Whiptail, diálogos para el terminal aparece primero en Atareao.