La Gaceta de Linux ...¡ haciendo a Linux un poco más divertido !

Diseñar Simples front-ends con dialog/Xdialog

Por Sunil Thomas Thonikuzhiyil

Traducción al español por Gustavo Conturzo
el día 13 de Mayo de 2005, para La Gaceta de Linux

1) Introducción

Este artículo introduce dialog y Xdialog para construir simples front-ends para los scripts de shell. Se asume que estás familiarizado con la programación de shell.
La última versión de este documento se puede encontrar en http://gnubox.dyndns.org:8080/~sunil/dialog.php.

dialog es una utilidad para construir front-ends basados en consola. Xdialog es un programa similar para X. Ambos programas son más o menos compatibles y fáciles de programar. Dialog viene con la mayoría de las distribuciones GNU/Linux. Si quieres compilar desde los fuentes, se puede obtener un tarball desde aquí. Xdialog está disponible desde aquí.

Ambos programas son software libre y corren en una variedad de plataformas *nix. La mayoría de los ejemplos dados en este tutorial se adaptan de ejemplos dados junto con los fuentes de dialog.

2) Temas fundamentales

Aquí está el primer script de dialog que probé. Muestra una simple caja SI/NO.
#!/bin/bash
DIALOG=${DIALOG=dialog}

$DIALOG --title " Mi primer diálogo" --clear \
--yesno "Hola , este es mi primer programa dialog" 10 30

case $? in
0)
echo "Si seleccionado.";;
1)
echo "No seleccionado.";;
255)
echo "ESC presionado.";;
esac

Copia las líneas de arriba a un archivo llamado yesno.sh y dale permiso de ejecutable.

$chmod u+x yesno.sh

Ahora intenta correr el programa.

$./yesno.sh

Abajo se da una captura de pantalla del programa de arriba.
yesno box
Ahora intenta cambiar la línea.

 DIALOG=${DIALOG=dialog}
to
DIALOG=${DIALOG=Xdialog}

Intenta correrlo desde una xterm. Obtuve la siguiente salida.
xyesno box

Vamos a tener una vista detallada del programa de arriba. La primera línea básicamente es un comentario que también indica que el shell bash se usa para ejecutar este programa.

DIALOG=${DIALOG=dialog}

La línea de arriba asigna a la variable DIALOG el valor 'dialog'. La caja de diálogo actual es dibujada por la siguiente línea.

  $DIALOG --title "Mi primer diálogo" --clear \
--yesno "Hola, este es mi primer programa dialog" 10 30

Las opciones usadas son
--title Esta opción establece el título de tu caja
--clear Esta opción limpia la pantalla antes de dibujar
--yesnobox Esto dibuja la caja con el texto dado dentro de ella.

El texto a ser impreso dentro de la caja yesno se da entre comilla dobles. Las envolturas del texto dependen del ancho de la caja. Puedes usar \n para forzar un salto de línea. Los últimos 2 números especifican el ancho y alto de la caja. Puedes moverte entre "yes" y "no" usando tabulaciones.

El programa dialog ahora espera la entrada del usuario. Cuando presiones enter sobre "yes" o "no" o si presionas la tecla escape el programa retorna y el valor de retorno está disponible en la variable de shell $? que puedes procesar después más adelante.

2) Leyendo la entrada

El siguiente programa lee una cadena que ingresas y la imprime.

#!/bin/sh
DIALOG=${DIALOG=dialog}
tempfile=`tempfile 2>/dev/null` || tempfile=/tmp/test$$
trap "rm -f $tempfile" 0 1 2 5 15

$DIALOG --title "Mi caja de entrada" --clear \
--inputbox "Hola, este es un ejemplo de caja de entrada\n
Prueba ingresar tu nombre abajo:" 16 51 2> $tempfile

retval=$?

case $retval in
0)
echo "La cadena ingresada es `cat $tempfile`";;
1)
echo "Cancelar presionado.";;
255)
if test -s $tempfile ; then
cat $tempfile
else
echo "ESC presionado."
fi
;;
esac

Intenta ejecutar el programa bajo consola y bajo X (después cambia dialog a Xdialog como arriba). Mira los resultados.
input box

Este programa es ligeramente más complejo que nuestro anterior programa yesno. Las siguientes líneas configuran un archivo temporal:

tempfile=`tempfile 2>/dev/null` || tempfile=/tmp/test$$
trap "rm -f $tempfile" 0 1 2 5 15

La primera línea de arriba intenta crear un archivo temporal usando la utilidad tempfile. Si falla, se configura manualmente un archivo temporal en /tmp. La segunda línea de arriba establece una rutina de captura. Cuando el script existe (normalmente o anormalmente) la captura elimina el archivo temporal. Los números mostrados son las señales que serán captadas.

Entonces dialog se invoca como abajo:

$DIALOG --title "Mi caja de entrada" --clear \
--inputbox "Hola, este es un ejemplo de caja de entrada\n
Prueba ingresar tu nombre abajo:" 16 51 2> $tempfile

El programa dialog escribe su salida en el error estándar por defecto. Por lo tanto la cadena de entrada que ingresaste se emite al error estándar que estamos redireccionando a nuestro archivo temporal. Puedes capturar el texto ingresado desde el archivo temporal para procesamiento posterior.

3) Construir un menú

Prueba el siguiente programa en consola y X (después cambia dialog a Xdialog como antes):

#!/bin/sh
DIALOG=${DIALOG=dialog}
tempfile=`tempfile 2>/dev/null` || tempfile=/tmp/test$$
trap "rm -f $tempfile" 0 1 2 5 15

$DIALOG --clear --title "Mi cantante HINDÚ favorito" \
--menu "Hola, eligue tu cantante HINDÚ favorito:" 20 51 4 \
"Rafi" "Mohammed Rafi" \
"Mukesh" "Mukesh" \
"Kishore" "Kishore Kumar" \
"Saigal" "K L Saigal" \
"Lata" "Lata Mangeshkar" \
"Yesudas" "K J Yesudas" 2> $tempfile

retval=$?

choice=`cat $tempfile`

case $retval in
0)
echo "'$choice' es tu cantante hindú favorito";;
1)
echo "Cancel presionado.";;
255)
echo "ESC presionado.";;
esac

Los resultados son los de abajo
Menu box
menu box

La lógica es exactamente similar a la caja de entrada. Redireccionamos la opción que has elegido a un archivo temporal y luego procesamos el valor de retorno de dialog y el contenido del archivo temporal.

4) Lista de radio y Lista de comprobación

Las listas de radio y listas de comprobación se pueden programar al igual que los menús. Abajo se da un ejemplo de lista de radio simple.

#! /bin/sh
DIALOG=${DIALOG=dialog}
tempfile=`tempfile 2>/dev/null` || tempfile=/tmp/test$$
trap "rm -f $tempfile" 0 1 2 5 15

$DIALOG --backtitle "Selecciona tu cantante favorito" \
--title "Mi cantante favorito" --clear \
--radiolist "Hola, puedes seleccionar tu cantante favorito aquí " 20 61 5 \
"Rafi" "Mohammed Rafi" off \
"Lata" "Lata Mangeshkar" ON \
"Hemant" "Hemant Kumar" off \
"Dey" "MannaDey" off \
"Kishore" "Kishore Kumar" off \
"Yesudas" "K. J. Yesudas" off 2> $tempfile

retval=$?

choice=`cat $tempfile`
case $retval in
0)
echo "'$choice' es tu cantante favorito";;
1)
echo "Cancel presionado.";;
255)
echo "ESC presionado.";;
esac

Abajo se muestra una captura de pantalla.

radiolist

Para poner a prueba la lista de comprobación sencillamente cambia la opción --radiolist en el programa de arriba a  --checklist.

5) Construir un Medidor

Un medidor basado en dialog se puede usar para indicar el progreso de tu programa. Construir un medidor es poco complicado. Mira el siguiente ejemplo:

#!/bin/sh
DIALOG=${DIALOG=dialog}

COUNT=10
(
while test $COUNT != 110
do
echo $COUNT
echo "XXX"
echo "The new\n\message ($COUNT percent)"
echo "XXX"
COUNT=`expr $COUNT + 10`
sleep 1
done
) |
$DIALOG --title "Mi Medidor" --gauge "Hola, este es un símbolo de medidor" 20 70 0

Aquí el programa dialog obtiene su entrada del código mostrado entre paréntesis. Este código emite el número a ser usado por el medidor y el mensaje a ser mostrado. El mensaje a ser mostrado en la caja del medidor debe estar rodeado por echo "XXX". Abajo se muestra la captura de pantalla de un medidor.
gauge

6) Selecciones de archivos

Abajo se muestra el código para una típica caja de diálogo de selección de archivo.

#!/bin/sh
DIALOG=${DIALOG=dialog}

FILE=`$DIALOG --stdout --title "Por favor elige un archivo" --fselect $HOME/ 14 48`

case $? in
0)
echo "\"$FILE\" elegido";;
1)
echo "Cancel presionado.";;
255)
echo "Caja cerrada.";;
esac

file selection

Por favor observa que el programa de arriba usa una técnica diferente para capturar el archivo seleccionado. Como mencioné anteriormente todas las salidas de dialog se envían al error estándar por defecto. Sin embargo, la opción --stdout se puede usar para enviar la información de salida a la salida estándar que a su vez puede ser asignada a una variable. Este truco se puede usar en el caso de otras cajas de diálogos como cajas de menú, cajas yesno, etc.

El díalogo de selección de archivos presenta dos paneles. Puedes usar la tecla Tab para cambiar entre los paneles y la barra espaciadora para seleccionar un archivo. También es posible escribir dentro de la caja de entrada del diálogo de selección de archivos.

7) Cajas de calendario y hora

a) Calendario

Una caja calendario muestra el mes, día y año separadamente en ventanas ajustables. Si los valores para día, mes o año faltan o son negativos, se usan los valores correspondientes de la fecha actual. Puedes incrementar o decrementar cualquiera de ellos usando las flechas izquierda, arriba, derecha y abajo. Usa h, j, k y l al estilo vi para moverte el arreglo de días en un mes. Usa la tecla Tab o Tab hacia atrás para moverte entre las ventanas. Si el año se da como cero, la fecha actual se usa como valor inicial. A la salida, la fecha se imprime en la forma día/mes/año.

#!/bin/sh
DIALOG=${DIALOG=dialog}

USERDATE=`$DIALOG --stdout --title "CALENDARIO" --calendar "Por favor elige una fecha..." 0 0 7 7 1981`

case $? in
0)
echo "Fecha ingresada: $USERDATE.";;
1)
echo "Cancel presionado.";;
255)
echo "Caja cerrada.";;
esac

calendar

b) Hora

La caja de diálogo hora te permite seleccionar la hora. Prueba el siguiente programa y mira cómo trabaja.

#!/bin/sh

DIALOG=${DIALOG=dialog}
USERTIME=`$DIALOG --stdout --title "CAJA DE HORA" --timebox "Por favor establece la hora..." 0 0 12 34 56`

case $? in
0)
echo "Hora ingresada: $USERTIME.";;
1)
echo "Cancel presionado.";;
255)
echo "Caja cerrada.";;
esac


time

8) Otras Características

Xdialog tiene algunas características adicionales tales como vista de árbol, cajas de orden, cajas de edición, etc. Por favor mira aquí. La página man de dialog tiene información interesante de algunas otras opciones tales como caja de contraseña,  tailbox, etc. También hay opciones para cambiar los colores, sombras, etc.

9) Propina

Puedes elegir entre dialog y Xdialog en tiempo de ejecución usando el siguiente recorte de código:

   if [ -z $DISPLAY ]
then
DIALOG=dialog
else
DIALOG=Xdialog
fi

Prueba este programa en consola así como en X y mira la diferencia.

 #!/bin/sh
if [ -z $DISPLAY ]
then
DIALOG=dialog
else
DIALOG=Xdialog
fi
$DIALOG --yesno "Es esto divertido" 0 0

10) Referencias

1) Página del manual para dialog

Esta es una lectura necesaria si estás planeando escribir algunos scripts de diálogo útiles. Hay otras varias opciones que te permiten modificar la vista y el sentido.

2) Ejemplos de dialog en http://www.fifi.org/doc/dialog/examples/.

Todos los ejemplos en este tutorial son versiones modificadas de los ejemplos encontrados aquí. Si tienes Debian GNU/Linux los ejemplos están disponibles en /usr/share/doc/dialog/examples.

3) La página de dialog de Thomas Dickey: http://dickey.his.com/dialog/

4) La página de dialog de Vincent Stemen http://hightek.org/dialog/.

Esta página tiene información de gran amplitud sobre varias versiones de dialog.

5) Documentación de Xdialog en http://thgodef.nerim.net/xdialog/doc/index.html.
Esta página tiene información exhaustiva sobre Xdialog.

 

[BIO] Trabajo como consultor en tecnología de la información en la Asamblea Legislativa de Kerala, Trivandrum India. He estado enganchado a Linux desde 1996. Tengo una Maestría en Ciencias de la Computación de la Universidad de Cochin. Estoy interesado en todo tipo de sistema operativo. En mi tiempo libre me encanta escuchar música clásica India.

Copyright © 2004, Sunil Thomas Thonikuzhiyil. Licencia de copia http://linuxgazette.net/copying.html

Publicado en el Número 101 de la Linux Gazette, Abril de 2004