Compartir

Compartir en GNU Social Compartir en Diaspora*

Xdialog, ventanas en scripts

En este remedo de artículo (por llamarlo de alguna forma) intentaré hacer un esbozo de lo que se puede hacer con la herramienta Xdialog. A través de Xdialog se puede conseguir introducir ventanas (o diálogos) en un shell-script para hacer más "amigable" la interacción con el usuario. En Ubuntu viene instalado por defecto la aplicación Zenity, que sirve para lo mismo que Xdialog pero tiene menos opciones, si alguien tiene interés en utilizar Zenity mejor que lea el artículo de Milmazz Zenity, mejorando la presencia de tus scripts. Además Xdialog es bastante compatible con dialog la aplicación de diálogos en modo texto (utiliza las librerías curses para mostrar los diálogos), por lo que un script con Xdialog se podría adaptar facilmente para tenerlo preparado para ejecutarlo en modo texto mediante dialog. ¿Qué necesitamos para hacer algo con Xdialog?
  • Conocimientos de shell-scripts
  • Obviamente tener instalado xdialog (y si no se tiene se soluciona facilmente con un sudo apt-get install xdialog)
  • Editor de texto: vi(m), emacs, joe, gedit, kate, scite o el que más nos guste.
Pero, antes de seguir, quizás sería conveniente responder a la pregunta... ¿Qué es Xdialog? Xdialog es una aplicación que lanza ventanas o diálogos que se pueden incluir dentro de un shell-script en lugar de los tradicionales comandos para mostrar información (echo) o recoger variables (read). Es decir si tenemos un script que le pide el nombre al usuario, en lugar de lanzar el típico read nombre se podrá lanzar Xdialog con los parámetros apropiados para que nos muestre una ventanita donde podamos escribir el nombre solicitado. Primeros ejemplos Vamos a ejecutar ahora unos ejemplos sencillos para ver como se muestran estos diálogos. Ejecutar en un terminal lo siguiente:
Xdialog --title "Mi primer Xdialog" --msgbox "Hola mundo" 0 0
Otra forma similar a la anterior pero poniendo duración al mensaje:
Xdialog --title "Mi primer Xdialog con caducidad" \
  --infobox "Hola mundo. \nEste mensaje desaparecerá en 5000 milisegundos" 0 0 5000
Si lo que queremos es un poco de interacción, por ejemplo haciendo una pregunta que se responda con un "Sí/No" podemos ejecutar:
Xdialog --title "Un Xdialog con pregunta" \
  --yesno "¿Quieres continuar con la charla?" 0 0
Antes de seguir vamos a echar un vistazo a los comandos anteriores En todos ellos hay un parámetro que se llama --title al que le sigue siempre un texto entrecomillado. Como parece lógico suponer mediante ese parámetro fijamos el título de la ventana que va a mostrar Xdialog También en todos los comandos que llevamos hasta ahora hay un par de ceros. Estos números indican el tamaño de la ventana que vamos a mostrar, al poner 0 en los dos lo único que se le dice a Xdialog es que ajuste automáticamente el tamaño teniendo en cuenta lo que tiene que mostrar. El resto de parámetros que le pasamos a Xdialog va en función del tipo de ventana que queremos mostrar:
  • msgbox -> muestra un mensaje hasta que cerramos la ventana
  • infobox -> muestra un mensaje hasta que cerramos la ventana o se cumpla el tiempo máximo que se le ha puesto (en milisegundos). En el ejemplo el tiempo es el 5000 que aparece al final
  • yesno -> muestra un mensaje y dos botones, uno para la opción Yes y otro para la opción No, según pulsemos a un botón o a otro devolverá la opción elegida.
  • ...
Recoger el resultado de Xdialog Dependiendo del tipo de ventana podremos encontrar el resultado en la variable especial $? o bien en la salida estándar de errores. - Un ejemplo del primer caso:
Xdialog --title "Un Xdialog con pregunta" \
   --yesno "¿Quieres continuar con la charla?" 0 0

resultado=$?
  • Si resultado contiene un 0 => Ha pulsado el botón SI
  • Si resultado contiene un 1 => Ha pulsado el botón NO
  • Si resultado contiene un 255 => Ha pulsado la tecla ESC
- Un ejemplo del segundo caso:
Xdialog --title "Titulo" --combobox "Selección de un valor" \
   0 0 "Valor 1" "Valor 2" "Valor 3" "Valor 4" "Valor 5" 2>/tmp/xdialog.tmp

resultado=`cat /tmp/xdialog.tmp`
Es decir redirigimos la salida estándar de errores (stderr) a un fichero y posteriormente cargamos el fichero en una variable Opciones de Xdialog Vamos a ver ahora más opciones de ejecución para el Xdialog. Pedir un campo (el equivalente al read variable):
Xdialog --title "Titulo de la ventana" --inputbox "Introduce tu nombre" 0 0
Igual que antes pero sin botón de Cancelar:
Xdialog --title "Titulo de la ventana" --no-cancel --inputbox "Introduce tu nombre" 0 0
O si queremos que aparezca un valor inicial:
Xdialog --title "Titulo de la ventana" --inputbox \
   "Introducir el nombre que quieres dar a tu máquina" 0 0 "localhost"
O si queremos ocultar el valor introducido (verificarlo, ver como quitar el check de ocultar tipado)
Xdialog --title "Titulo de la ventana" --password --inputbox "Introduce tu password" 0 0
Podemos pedir en la misma ventana dos y hasta tres campos sin más que utilizar la opción --2inputsbox o --3inputsbox:
Xdialog --title "Titulo de la ventana" --password --password \
      --3inputsbox "Datos del usuario" 0 0 "Usuario" "" \
           "Password" "" "Repite la Password" ""
Elegir un valor de un campo seleccionable:
Xdialog --title "Titulo de la ventana" --combobox "Nivel de estudios" 0 0 \
    "Primaria" "Secundaria" "Bachillerato" "Universitario" "Postgrado"
Elegir un valor de una lista:
Xdialog --title "Titulo de la ventana" --menubox "Nivel de estudios" 0 0 0 \
            "primaria" "Primaria" "secundaria" "Secundaria" \
            "bachillerato" "Bachillerato" "universitario" "Universitario" \
            "postgrado" "Postgrado"
El tercer cero se refiere a la altura del menú, igualmente poniendo 0 le dejamos a Xdialog que lo ajuste automáticamente. Elegir un valor de un rango numérico (corriendo una barra horizontal):
Xdialog --title "Titulo de la ventana" --rangebox "¿Qué nota le das a esta charla" 0 0 1 10 2

Rangebox

En el ejemplo se muestra una barra en el que el extremo inferior es 1 y el superior es 10. El valor inicial es 2. Elegir un valor de un rango numérico (aumentando/disminuyendo los números) (revisar):
Xdialog --title "Titulo de la ventana" --spinbox "¿Qué nota le das a esta charla" 0 0 1 10 2 "Nota"

Spinbox

De forma similar a la opción inputbox, existen también --2rangesbox, --3rangesbox, --2spinsbox y --3spinsbox. Mostrar el contenido de un fichero
Xdialog --title "Titulo de la ventana" --textbox ${HOME}/.bashrc 0 0
Editar el contenido de un fichero
Xdialog --title "Titulo de la ventana" --editbox ${HOME}/.bashrc 0 0
En este caso para que se guarden los cambios es preciso "capturarlos" de stderr y volcarlos en el fichero:
Xdialog --title "Titulo de la ventana" --editbox ${HOME}/.bashrc 0 0 2>/tmp/bashrc
cp /tmp/bashrc ${HOME}/.bashrc
Mostrar un fichero al que están continuamente añadiendo líneas al final (por ejemplo un log) al estilo de tail -f:
Xdialog --title "Titulo de la ventana" --tailbox ${HOME}/mifichero.log 0 0
Para probar lo anterior podemos hacer lo siguiente:
touch ${HOME}/mifichero.log
Xdialog --title "Titulo de la ventana" --tailbox ${HOME}/mifichero.log 0 0 &
echo "Esta linea debe salir en la ventana del Xdialog" >> ${HOME}/mifichero.log
Hemos lanzado Xdialog en background (el & del final) para poder liberar el terminal y poder añadir una línea al fichero mientras la ventana del Xdialog sigue abierta. Otra opción hubiera sido lanzar el Xdialog (sin el &) en un terminal y el echo en otro. Ver un log de systema:
Xdialog --title "Titulo de la ventana" --logbox /var/log/syslog 0 0
Chequear una opción (o más de una) entre varias posibilidades:
Xdialog --title "Titulo de la ventana" --checklist \
                  "¿Qué distribuciones de GNU/Linux usas?" 0 0 0 \
                  "Debian" "Mamá Debian" "off" \
                  "Ubuntu" "Ubuntu por supuesto" "on" \
                  "Fedora" "Fedora también existe" "off" \
                  "Ninguna" "No uso GNU/Linux" "unavailable"

checklist

Devuelve las opciones separadas por el carácter / Es decir si ha marcado Debian y Ubuntu devolverá: Debian/Ubuntu Chequear una opción entre varias:
Xdialog --title "Titulo de la ventana" --radiolist \
                  "¿Qué distribuciones de GNU/Linux usas?" 0 0 0 \
                  "Debian" "Mamá Debian" "off" \
                  "Ubuntu" "Ubuntu por supuesto" "on" \
                  "Fedora" "Fedora también existe" "off" \
                  "Ninguna" "No uso GNU/Linux" "unavailable"

radiolist

Seleccionar un fichero
Xdialog --title "Titulo de la ventana" --fselect ${HOME} 0 0
Devuelve el nombre completo (ruta incluida) del fichero seleccionado Seleccionar un directorio
Xdialog --title "Titulo de la ventana" --dselect ${HOME} 0 0
Mostrar un calendario para marcar un día:
Xdialog --title "Titulo de la ventana" --calendar "Calendario" 0 0 28 11 2007
Selecciona la hora (muestra la hora actual)
Xdialog --title "Titulo" --timebox "Selecciona la hora" 0 0
Elegir varias opciones "moviendo" de una ventana a otra:
Xdialog --title "Titulo de la ventana" --buildlist "Distribuciones que uso" \
            0 0 0 "ubuntu" "Ubuntu" "on" "fedora" "Fedora" "off" \
                  "debian" "Debian" "on" "mandriva" "Mandriva" "off"

Buildlist

El resultado lo devuelve de forma similar al checklist, así si ha elegido Fedora y Mandriva devolverá: fedora/mandriva Mostrar un árbol
Xdialog --title "Titulo de la ventana" --treeview \
           "Distribuciones según sistema de paquetes" 0 0 0 \
            "Deb" "Paquetes deb" "off" 1 \
              "Debian" "Distribución Debian" "off" 2 \
              "Ubuntu" "Distribución Ubuntu" "off" 2 \
            "Rpm" "Paquetes rpm" "off" 1 \
              "Fedora" "Distribución Fedora" "off" 2 \
              "Mandriva" "Distribución Mandriva" "off" 2

Treeview

Ejecutando
Xdialog --help
Obtenemos una lista completa de las opciones de Xdialog. Ejemplo de uso en un shell-script
#!/bin/bash
DIR_CONTACTOS=${HOME}/cutre-contactos

DIR_TMP=${DIR_CONTACTOS}/tmp

function nuevoContacto () {

    Xdialog --title "Nuevo contacto" --3inputsbox "Nombre del contacto" 0 0 \
               "Nombre corto" "${nb_corto}" "Nombre completo" "${nb_completo}" \
               "Email" "${email}" 2>${HOME}/cutre-contactos/tmp/nuevo.txt
    ret=$?

    if [ $ret != 0 ]; then
       nuevoContacto
    fi

    nb_corto=`cat ${DIR_TMP}/nuevo.txt | cut -d "/" -f 1`
    nb_completo=`cat ${DIR_TMP}/nuevo.txt | cut -d "/" -f 2`
    email=`cat ${DIR_TMP}/nuevo.txt | cut -d "/" -f 3`

    if [ "${nb_corto}" = "" -o "${nb_completo}" = "" -o "${email}" = "" ]; then
       nuevoContacto
    fi

    if [ -d ${DIR_CONTACTOS}/${nb_corto} ]; then
        Xdialog --title "Contacto ya existe" --msgbox \
            "El contacto ${nb_corto} ya existe" 0 0
        return
    fi

    mkdir ${DIR_CONTACTOS}/${nb_corto}
    echo ${nb_completo} > ${DIR_CONTACTOS}/${nb_corto}/nombre
    echo ${email}  > ${DIR_CONTACTOS}/${nb_corto}/email

}

function borrarContacto() {
   Xdialog --title "Borrar contacto" --infobox "No implementado" 0 0 5000
}

function modificarContacto() {
   Xdialog --title "Modificar contacto" --infobox "No implementado" 0 0 5000
}

function buscarContacto() {
   Xdialog --title "Buscar contacto" --inputbox "Buscar contacto" \
            0 0 "${nb_corto}" 2>${DIR_TMP}/buscar.txt
   if [ $? = 0 ]; then
      nb_corto=`cat ${DIR_TMP}/buscar.txt`
      if [ "${nb_corto}" != "" ]; then
         if [ ! -d ${DIR_CONTACTOS}/${nb_corto} ]; then
            Xdialog --title "Contacto no existe" --msgbox \
                 "El contacto ${nb_corto} no existe" 0 0
            return
         else
            nb_completo=`cat ${DIR_CONTACTOS}/${nb_corto}/nombre`
            email=`cat ${DIR_CONTACTOS}/${nb_corto}/email`
            Xdialog --title "Datos del contacto" --msgbox \
               "Contacto: ${nb_corto}\nNombre: ${nb_completo}\nEmail: ${email}\n" 0 0
         fi
      else
         return
      fi
   fi
}

#Crea en nuestro home los directorios que necesita
mkdir -p ${DIR_TMP} 2>/dev/null

while true ; do
 nb_corto=""
 nb_completo=""
 email=""

 Xdialog --title "Cutre-Contactos" --menubox "Acción a realizar" \
                   0 0 0 "nuevo" "Nuevo Contacto" "borrar" "Borrar Contacto" \
                         "modificar" "Modificar Contacto" \
                         "buscar" "Buscar Contacto" \
                         "salir" "Salir" 2>${DIR_TMP}/accion.txt
 retorno=$?
 if [ $retorno != 0 ]; then
       exit
 fi
 accion=`cat ${DIR_TMP}/accion.txt`
 case $accion in
  nuevo)
     nuevoContacto
   ;;
  borrar)
     borrarContacto
   ;;
  modificar)
        modificarContacto
   ;;
  buscar)
     buscarContacto
   ;;
  *)
     exit 1
   ;;
 esac

done
Referencias Documentación de Xdialog

Comentarios

muy bueno el tutorial para mi

muy bueno el tutorial para mi que au estoy empezando..

B. Tardes. Voy a realizar una

B. Tardes. Voy a realizar una exposición del LINUX, pero necesito imágenes de pantalla que especifique como cerrar sesion y apagar el computador, pero es primera vez que oi de LINUX, y no tengo idea. Les agradeceria cualquier ayuda,Salu2

Hola, una pregunta. ¿Cómo

Hola, una pregunta. ¿Cómo harías para dirigir los mensajes de salida del comando

$ sudo shutdown -h $hora

de forma que se puedan visualizar como ventanas de diálogo con Xdialog?

Es que tengo un script para programar el apagado del PC a una hora determinada, y me gustaría poder cerrar la terminal pero que me estuvieran apareciendo los mensajes en ventanas de diálogo, con los mensajes del estilo:

Emitir mensajes desde root@nombre_máquina
(unknown) en 17:00 ...

¡El sistema se apagará por halt en 60 minutos!

De antemano muchas gracias.

Argel.

Efectivamente esa línea debía

Efectivamente esa línea debía estar separada en dos, muchas gracias por la corrección.

Hola, navegando por el

Hola, navegando por el google, di con esta pagina, por la cual me fue de mucha utilidad para mi, que estoy empezando en el mundo de ubuntu y de la programacion de scripts y sobre todo el uso de las ventanas. soy novato en realidad que tiene cierto interes en aprender a programar como un pasatiempo y poder aportar algo en un futuro no muy lejano al software libre. Te agradesco de ante mano por la gran aportacion de este documento. solo como sugerencia, creo que hay un peque#o error en el ultimo script como ejemplo, creo que se junto o se unio la primera linea. ejemplo:

esta
#!/bin/bashDIR_CONTACTOS=${HOME}/cutre-contactos

debe ser:
#!/bin/bash
DIR_CONTACTOS=${HOME}/cutre-contactos

espero que sirva a algun novato como yo

[...] Xdialog, ventanas en

[...] Xdialog, ventanas en Scripts Tambien te puede interesar: [...]