Aprende GNU/Linux 15

Scripts en Linux con estilo

tux_con_estiloEn artículos anteriores hemos hablado sobre como crear los scripts y muchas de las nociones necesarias para poder escribirlos,  pero en muchas ocasiones después de trabajar en un script y conseguir que realice las operaciones como queremos, nos quedamos con las ganas de darle un toque más y conseguir que la interacción con el usuario sea más vistosa. En este artículo voy a tratar de explicar unas cuantas maneras con las que vamos a poder darles a nuestros scripts un aspecto mucho más cuidado y elegante.

Existen diferentes métodos de dotar de estilo a nuestros scripts, las voy a ir numerando y explicando una por una, tratando de hablar de cómo funcionan y sus características principales además de exponer ejemplos. Es importante tener en cuenta que como en los mismos scripts, la complejidad que se  le quiera dar a estas herramientas es las ganas de uno mismo, así que al lío.

1- El poder de ASCII

Aunque suene algo trivial, la mejor forma de que nuestros scripts luzcan mejor es mediante las buenas practicas de la utilización de los caracteres ASCII. Mostrar la información clara y con los saltos de linea adecuados es trascendental para que no exista confusión en la lectura de datos. Además de utilizar adecuadamente el comando echo también existen otros truquillos que pueden mejorar el aspecto, pero hay que usarlos con cuidado porque también pueden resultar en justo lo contrario.

Echo:

El comando echo nos permite mandar por la salida estándar ( que por defecto es la pantalla) la información que le pasemos como parámetro, pero además de esto tiene unas secuencias de escape que nos van ayudar a ordenar esta información:

Secuencias de escape echo
Secuencia de escape   Descripción
\a Emite la alerta del sistema.
\b Borra hacia atrás un carácter.
\c Suprime toda salida siguiente a esta secuencia.
\n Salto de linea.
\r Retorno de carro.
\t Tabulador.

 

Para poder utilizar estas secuencias de escape el valor que tenemos que pasar a echo tiene que estar encerrado entre comillas dobles o sencillas ( como un string ) y adicionalmente tenemos que llamar a echo con la opción -e, veamos un ejemplo:

#!/bin/bash

echo -e  "Función del script: \n \t Demostración para articulo scripts con estilo"

Correcto

Resultado :

pruebaecho

#!/bin/bash

echo Función del script: \n \t Demostración para articulo scripts con estilo

Incorrecto

Clear:

Si el script en cuestión es un script bastante largo, puede que sea conveniente que la primera orden a la que llame sea un clear, de esta forma limpiamos la terminal completamente  y es mas fácil visualizar el contenido del script. Esta opción sobretodo es recomendable en el caso de uso de menús y herramientas que requieran la atención del usuario.

Barras de separación:

Otro método que suele mejorar el aspecto es la separación de los textos mediante barras. Por ejemplo:

En un scripts con solamente un clear y después echo’s el resultado es el siguiente:

Script de demostracion de ovtoaster
Nombre : estilo.sh
Proposito : demostracion
Creador : OvToaster

Teniendo en cuenta que el texto “Script de demostración de OVtoaster” es el titulo del script, si lo separamos con barras el resultado queda en:

____________________________________
Script de demostración de OVtoaster

____________________________________

Nombre : estilo.sh
Propósito : demostración
Creador : OvToaster

Titulos Ascii:

También podemos dar más estilo a nuestros textos con herramientas como el ASCII generator, que no siempre nos va a servir, pero puede ser curioso, el resultado es algo así:

Generador ascii

En este caso hay que tener en cuenta que algunos textos llevan comillas y tenemos que quitarlas
Cuidado

Pulsar tecla para continuar:

Otra buena práctica para los scripts largos y sobretodo en scripts en los que vamos a realizar cambios críticos, es realizar pausas para que no se realice todo del tirón ( depende de lo que queramos ),   para conseguir esto vale con añadir :

read -rsp $'Pulsa cualquier tecla para continuar\n' -n1 key

Podemos sustituir “Pulsa cualquier tecla para continuar” por cualquier otro texto.

2- El comando tput

Una opción más visual es el comando tput, este tiene muchas utilidades como por ejemplo, posicionar el cursor en cualquier lugar de la terminal,  cambiar los colores de los caracteres y sus fondos, darles atributos a las letras, recopilar el tamaño de la terminal…

Es un comando bastante extenso pero con una explicación básica es suficiente para entender su funcionamiento y después se pueden consultar todas sus posibilidades mediante man tput o en la web de la universidad de utah ( Ingles ).

Aquí tenéis una lista de las principales opciones de tput ( gracias a Twikibar ) :

Opciones tput
Principales Opciones del Comando tput
rc   Restore Cursor position – Coloca el cursor en la posición marcada por el último sc
Opciones de tput   Descripción
cup lin col   Cursor Position – Posiciona el cursor en la línea lin y columna col. El origen es cero
bold   Coloca la pantalla en modo de realce
rev   Coloca la pantalla en modo de vídeo inverso
smso   Idéntico al anterior
smul   A partir de esta instrucción, los caracteres tecleados aparecerán sublineados en la pantalla
blink   Los caracteres tecleados aparecerán intermitentes
sgr0   Después de usar uno de los atributos de arriba, se usa este para restaurar la pantalla a su modo normal
reset   Limpia la pantalla y restaura sus definiciones de acuerdo con el terminfo o sea, la pantalla vuelve al patrón definido por la variable $TERM
lines   Devuelve la cantidad de líneas de la pantalla en el momento de la instrucción
cols   Devuelve la cantidad de columnas de la pantalla en el momento de la instrucción
el   Erase Line – Borra la línea a partir de la posición del cursor
ed   Erase Display – Borra la pantalla a partir de la posición del cursor
il n   Insert Lines – Introduce n líneas a partir de la posición del cursor
dl n   Delete Lines – Borra n líneas a partir de la posición del cursor
ech n   Erase CHaracters – Borra n caracteres a partir de la posición del cursor
sc   Save Cursor position – Graba la posición del cursor

Dicho todo esto, la mejor manera de verlo es mediante un ejemplo en el que vamos a usar algunas opciones de tput:

#! /bin/bash

# Limpiamos la pantalla
tput clear
 
# Movemos el cursos a la posición 3,15 en la pantalla (arriba, izquierda = 0,0)
tput cup 3 18
 
# Damos color a las letras
tput setaf 5
echo "OVTOASTER"
tput sgr0

# Movemos el cursor de posición
tput cup 5 17

# Coloca la pantalla en modo de vídeo inverso 
tput rev
echo "MENU PRINCIPAL"
tput sgr0

# Movemos el cursor de posición
tput cup 7 15
echo "1. Primera opcion"

# Movemos el cursor de posición
tput cup 8 15
echo "2. Segunda opcion"
 
# Coloca la pantalla en modo de realce 
tput bold
# Movemos el cursor de posición
tput cup 12 15
read -p "Introduce tu eleccion [1-2] " choice
 
tput clear
tput sgr0
# Coloca el cursor en la posición marcada por el último sc
tput rc

El resultado es el siguiente:

tput

¡Como veis con poca cosa el resultado visual mejora notablemente!

3- El comando Dialog

El comando Dialog como su propio nombre indica se usa para recopilar o entregar información a los usuarios mediante cajas de diálogos. El man de Dialog nos indica las diferentes opciones que tiene:

calendar, checklist, fselect, gauge, infobox, inputbox, menu, msgbox (message), password, radiolist, tailbox,tailboxbg, textbox, timebox, and yesno (yes/no).

Veamos un ejemplo de su funcionamiento:

#!/bin/bash
dialog --title "¿Desea instalar?" \
--backtitle "Ejemplo de Dialog por OvToaster" \
--yesno "¿Estas seguro de querer instalar el programa?" 7 60
 
# Recopilamos la información de salida
# 0 significa que se a pulsado el botón [si].
# 1 significa que se a pulsado el botón [no].
# 255 significa que se a pulsado el botón [Esc].

response=$?
case $response in
   0) echo "Instalando...";;
   1) echo "Instalación cancelada";;
   255) echo "Instalación cancelada";;
esac

El resultado de este ejemplo es el siguiente :

dialog

Como se puede ver son diálogos dentro de la terminal, jugando con los píxeles de esta, por lo que es una utilidad que no requiere de elementos externos para funcionar. Como apunte final sobre esta herramienta, decir que es posible utilizar más de un dialogo en un mismo script.

4- El comando Zenity

Se podría decir que Zenity es la versión 2.0 del comando Dialog, ofrece diálogos mas visuales y complejos basados en GTK+. Como Dialog, Zenity nos permite recopilar información, mostrarla, interrumpir procesos… en resumen, nos permite interactuar con el usuario, pero en este caso los diálogos se apoyan en la interfaz GTK+ y son independientes a la terminal.

Veamos un ejemplo :

#!/bin/bash

# Pedimos la palabra a buscar
palabra=$(if zenity --entry \
--title="Buscar palabra" \
--text="Introduza la palabra a buscar" \
--entry-text "palabra"
  then echo $?
  else echo "No ha especificado ninguna palabra
fi)
# Seleccionamos el fichero en el que vamos a realizar la búsqueda
fichero=$(zenity --file-selection --title " Seleccione fichero en el que desea buscar" $HOME)
# Buscamos en el fichero
resultado=$(grep -i "$palabra" "$fichero")
# Mostramos el resultado
zenity --warning --title="Resultado" --text="$resultado"

En este ejemplo usamos diferentes diálogos de Zenity y básicamente lo que hace es pedir una palabra ( –entry ),  pedir un fichero ( –file-selection ),  realizar la búsqueda de la palabra en el fichero mediante grep y después mostrar el resultado en un –warning. Los diálogos en secuencia son así:

Zenity

Lo interesante no es el resultado, si no los diálogos en si, totalmente gráficos y bastante configurables. Es una utilidad bastante profunda y muy útil, en la pagina oficial de Gnome hay una guía con todos los Dialogs y opciones disponibles. De todos modos aquí tenéis los los diálogos principales :

Diálogos Zenity

Diálogo de calendario = –calendar.
Diálogo de contraseña = –password.
Diálogo de escala = –scale.
Diálogo de formularios = –forms.
Diálogo de lista = –list.
Diálogo de progreso = –progress.
Diálogo de selección de archivos = –file-selection.
Diálogo de selección de color = –color-selection.
Diálogo para la entrada de texto = –entry.
Diálogo para la texto de información = –text-info.
Icono de notificación = –notification.
Diálogo de advertencia = –warning.
Diálogo de error = –error.
Diálogo de información = –info.
Diálogo de pregunta = –question.

Se podría decir que Zenity es la opción más “gráfica” para tunear nuestros scripts, pero evidentemente esta opción no es válida si Zenity no está instalado ( en Gnome siempre viene instalado y en algunos otros entornos también ) , pero si queremos que funcione en un entorno sin interfaz gráfica no es la opción correcta.

Aquí tenéis una visión general de todos los diálogos de Zenity :

dialogosZenity

5- El comando Kdialog

Kdialog es el equivalente de Zenity en aplicaciones basadas en Qt y desarrollado principalmente para Kde, funciona de una forma muy similar por lo que no voy a exponer un ejemplo, aunque si que quiero comentar que soy más fan de las interfaces Qt que de las Gtk+  

Aquí tenéis los principales diálogos de Kdialog:

Diálogos Kdialog
Diálogos de Kdialog
Opciones Descripción
— yesno Cuadro de texto de preguntas con botones de si/no
– – yesnocancel texto Cuadro de texto de mensajes con botones de si/no/cancelar
– – warningyesno texto Cuadro de aviso de mensajes con botones de si/no
– – warningcontinuecancel texto Cuadro de aviso de mensajes con botones de continuar/cancelar
– – warningyesnocancel texto Cuadro de aviso de mensajes con botones de si/no/cancelar
– – sorry texto Cuadro de mensaje de ‘Lo sentimos’
– – error texto Cuadro de mensaje de ‘error’
– – msgbox texto Cuadro de diálogo de mensaje
– – inputbox texto inicial Cuadro de diálogo de entrada
– – password texto Diálogo de contraseña
– – textbox file [ancho] [alto] Cuadro de diálogo de texto
– – combobox texto [tag item] [tag item] … Diálogo de lista desplegable
– – menu texto [tag item] [tag item] … Diálogo de menú
– – checklist texto [tag item status] … Diálogo de lista de comprobación
– – radiolist texto [tag item status] … Diálogo de lista de selecciones excluyentes
– – getopenfilename [DirInicial] [filtro] El diálogo de archivos abre un archivo existente
– – getsavefilename [DirInicial] [filtro] Diálogo de archivos para guardar un archivo
– – getexistingdirectory [Dirinicial] Diálogo de archivo para seleccionar un directorio existente
– – getopenurl [startDir] [filtro] El diálogo de archivos abre una URL existente
– – getsaveurl [startDir] [filtro] Diálogo de archivos para guardar una URL
– – title texto Título de diálogo

Y este es su aspecto:

dialogsKdialog

En la pagina de KDE tienen un excelente tutorial en ingles ( se entiende fácil ) : Tutorial Kdialog

Un ultimo apunte

Puede que en la mayoría de las ocasiones los scripts que escribimos sean para uso personal y no requieran de este tipo de herramientas, pero aconsejo que si un script lo van a utilizar terceras personas se intente hacer lo mas amigable posible, sobre todo si estas personas no tienen conocimientos sobre scripting. Pero si el script va realizar una función sin la necesidad de interactuar con el usuario, lo mejor es no utilizar ninguna de estas herramientas para que el script complete su cometido lo mas rápido posible.

El grado de “tunning” que le queramos dar a nuestras pequeñas creaciones es completamente personal, porque de por si, todas estas utilidades no ofrecen ninguna funcionalidad.

Si queréis aprender mas sobre la terminal y los scripts aquí tenéis todos los artículos escritos hasta la fecha sobre el tema:

 

¡Un saludo!

 

Sobre el autor / 

AsierPH

Entusiasta de las tecnologías libres y fundador de OvToaster.com | “Las obras de conocimiento deben ser libres, no hay excusas para que no sea así“

Articulos relacionados

15 comentarios

  1. Luis 5 septiembre, 2016 at 12:03 am -  Responder

    Me lei toda la guia. Explicas muy bien.

  2. Darkhogg 24 octubre, 2014 at 9:28 am -  Responder

    El primer punto me parecen consejos TERRIBLES. Me explico.

    clear: Si el script es una colección de echos y printfs que simplemente van mostrado información línea a línea, es más interesante minimizar la cantidad de mensajes que otra cosa. Si el usuario quiere eliminar la pantalla que lo haga por su cuenta. Si la aplicación es intensiva en menús, puede ser buena práctica, pero en ese caso considera si no sería mejor utilizar argumentos en línea de comandos
    Si la aplicación es gráfica (entre comillas) y vamos a modificar la pantalla abundantemente, en su lugar podemos utilizar:
    tput smcup
    trap EXIT ‘tput rmcup’
    Esto hará que la pantalla se salve y restaure al estilo curses

    títulos y barras de separación:
    Personalmente no me gustan pero es cuestión de gustos supongo. Una salida convenientemente indentada que agrupe el proceso por niveles, saltos de línea bien puestos, etc. pueden hacer maravillas (los scripts de Arch Linux como makepkg son buen ejemplo)

    “pulsa una tecla para continuar”
    Por favor, NO. La idea de un script es que sea cuanto más automático mejor. Si la información que se está mostrando es CRÍTICA para continuar, vale. Por ejemplo, si estamos formateándole al usuario una partición, mejor informarle primero. Pero si no, continuamos el script y punto. Ya navegará el usuario por el cacklog, que para eso está.

    Por lo demás, me ha gustado bastante. Tened siempre en cuenta que dialog es la opción más interoperable puesto que no requiere más que una ventana de terminal. Zenity/kdialog requieren una sesión activa en X y por tanto no podemos ejecutarlas desde tty.

    Como consejo extra, si se trata de un script que automatiza alguna tarea típica, por favor HACEDLO CUANTO MENOS INTERACTIVO SEA POSIBLE. A las malas, con un switch que permita llamarlo o no de forma interactiva y/o con detección de tty (para no funcionar interactivamente si no hay terminal asociada).

    • AsierPH 24 octubre, 2014 at 9:53 am -  Responder

      ¡Buenas Darkhogg!, lo primero gracias por comentar y dar tu opinión, las criticas constructivas siempre son bien recibidas.
      Respecto al primer punto que comentas, creo que la palabra adecuada no es terrible pero puedo entender tu punto de vista, si que es cierto que estas practicas solo sirven si no queremos utilizar otros programas, pero mi intención mas que recomendar su uso era dar a conocer ciertas practicas que pueden ayudar a dar una visión de las posibles mejoras que se les puede dar a los scripts en el apartado gráfico. Evidentemente cada uno tiene sus gustos y dependiendo del script las opciones adecuadas son unas o otras.
      Por ejemplo creo que en el caso del clear, en scripts que interactúan con el usuario puede ser útil si se utilizan menús y este tipo de herramientas, aunque evidentemente es prescindible.
      Sobre “pulsar una tecla para continuar” como bien indicas, en algunos scripts puede haber momentos que sea mejor parar y avisar antes de realizar algún cambio en el sistema e incluso en casos menos trascendentales.

      También decir que el ultimo consejo que das es muy cierto, los scripts en su gran mayoría tienen que tirar para adelante y terminar lo antes posible, pero evidentemente este articulo no esta escrito para este tipo de script 🙂
      Un saludo y gracias de nuevo

  3. Lacasito 23 octubre, 2014 at 7:31 pm -  Responder

    Hace poco oí hablar de que Zenity estaba un poco parado. Probé YAD, pero me parece engorroso. ¿Podrías intentar explicar un poco cómo se usa?

    Gracias

    • AsierPH 23 octubre, 2014 at 9:14 pm -  Responder

      ¡Buenas Lacasito! Yad casi no lo he usado ( simplemente he leído sobre el y lo he probado un poco ), pero la mecánica es la misma, a ver si saco tiempo este fin de semana y lo añado al articulo
      Gracias por comentar 🙂

  4. nacho 23 octubre, 2014 at 8:07 am -  Responder

    Eres un crack, me acabas de abrir el mundo a crear scripts de mejor calidad, mucha gracias, vas de frente a mis fuentes rss.

    • AsierPH 23 octubre, 2014 at 9:15 am -  Responder

      ¡Gracias a ti Nacho! Me alegra que te sea de utilidad 🙂

  5. Guido Rolon 22 octubre, 2014 at 10:30 pm -  Responder

    Me gusto mucho el articulo.

    Me recuerda esto a un comando de Unix que se llamaba banner

    • AsierPH 22 octubre, 2014 at 11:48 pm -  Responder

      ¡Gracias por comentar Guido!
      Me pensé si incluir este tipo de programas (banner y figlet) pero creo que es mas sencillo con herramientas on-line :), aun así puede que lo incluía mas adelante, son herramientas muy curiosas jajaja.

  6. Alberto 20 octubre, 2014 at 5:44 pm -  Responder

    A favoritos, gracias!!
    Gracias!!!!!!

    • AsierPH 20 octubre, 2014 at 5:53 pm -  Responder

      ¡Gracias por comentar Alberto!

  7. davidochobits 20 octubre, 2014 at 12:23 pm -  Responder

    Hola!
    Un gran aporte, directo a favoritos : )
    Saludos!

    • AsierPH 20 octubre, 2014 at 12:47 pm -  Responder

      ¡Muchas gracias David!
      Un saludo 🙂

  8. Henry 20 octubre, 2014 at 10:13 am -  Responder

    ¡Me encanta!
    Muchas gracias, AsierPH.

    • AsierPH 20 octubre, 2014 at 10:51 am -  Responder

      ¡Gracias a ti Henry!

Deja tu comentario

Tu correo no sera publicado. Los campos requeridos están marcados *