En la última publicación hablamos de expresiones regulares y vimos como podíamos utilizarlas en sed y awk para el procesamiento de texto, además, discutimos anteriormente el comando Sed de Linux y el comando awk. Durante la serie, hemos escrito pequeños scripts de shell, pero no mezclamos las cosas, creo que deberíamos ir un paso más allá y escribir scripts de shell utilices
Sin embargo, los scripts en esta publicación te ayudaran a mejorar tus habilidades de escritura de scripts.
Table of Contents
Enviando Mensajes con scripts de shell
Puedes enviar mensajes a alguien a través de tu teléfono móvil o correo electrónico, pero un método, que no se utiliza mas comúnmente, es enviar mensajes directamente desde el terminal de usuarios.
Vamos a construir scripts de bash que enviaran un mensaje a un usuario que este logueado en el sistema de Linux.
Para este script de shell simple, solo necesitamos unas cuantas funciones. La mayoría de los comandos requeridos son comunes y los hemos estado cubriendo en nuestra serie de scripting de shell; puedes revisarlos en nuestras publicaciones anteriores.
Primero, necesitamos conocer quien esta logueado. Esto puede ser realizado utilizando el comando who que muestras todos los usuarios logueados.
$ who
Para enviar un mensaje necesitas el nombre de usuario y su terminal actual.
Necesitas conocer si los mensajes están permitidos o no para ese usuario utilizando el comando mesg.
$ mesg
Si el resultado muestras “is y” esto significa que la mensajería está permitida. Si el resultado muestra “is n”, eso significa que la mensajería no está permitida.
Para revisar los estados de todos los usuarios logueados utiliza el comando who con la opción -T.
$ who -T
Si observas un guion (-) eso significa que los mensajes estas deshabilitados y si ves un símbolo de suma (+) esto significa que los mensajes están activados.
Para permitir mensajes, escribe mesg con la opción “y” de la siguiente manera:
$ mesg y
Luego, mostrara “is y” lo cual significa que los mensajes están permitidos para ese usuario.
Por su puesto, necesitamos otro usuario que sea capaz de comunicarse, así que en mi caso voy a conectarme a mi PC utilizando SSH y listo, ya estaré conectado con mi usuario así que ahora tengo dos usuarios logueados en el sistema.
Vamos a ver como enviar un mensaje.
El Comando Escribir
El comando escribir es utilizado para enviar mensajes entre usuarios utilizando el nombre de usuario y la terminal.
Para los usuarios que hayan ingresado en el ambiente grafico (KDE, Gnome, Cinnamon o cualquiera), estos no pueden recibir mensajes, tienen que entrar en la terminal y loguearse
Vamos a enviar un mensaje al usuario testuser desde mi usuario likegeeks de la siguiente forma:
$ write testuser pts/1
Escribe el comando write seguido por el usuario y la terminal, por ultimo presiona Enter.
Cuando presionas Enter, puedes empezar a escribir tu mensaje. Después de finalizar el mensaje, puedes enviar el mismo presionando la combinación de teclas Ctrl+D lo cual es la señal de fin de archivo. Te recomiendo que revises mi publicación acerca de señales y trabajos.
El receptor puede reconocer cual usuario en que terminal envía el mensaje. EOF significa que el mensaje ha finalizado.
Creo que ahora tenemos todas las partes para construir nuestro script de shell.
Creando el Script de Emisión
Antes de crear nuestro script de shell, necesitamos determinar si el usuario al que queremos enviarle el mensaje está conectado en el sistema, esto puede realizarse utilizando el comando who para determinar eso.
logged=$(who | grep -i -m 1 $1 | awk '{print $1}')
Obtenemos el usuario logueado utilizando el comando grep. La opción -m 1 es utilizada en caso de que haya múltiples sesiones abiertas por el mismo usuario.
Si el usuario no está en línea, el comando grep no retornara nada.
Esta salida es pasada por una tubería a él comando awk. Este comando retornara solo el primer ítem. La salida final del comando awk es almacenada en la variable logged_on.
Luego debemos revisar si la variable contiene algo o no:
1 2 3 4 5 6 7 8 9 | if [ -z $logged ]; then echo "$1 is not logged on." echo "Exit" exit fi |
Te recomiendo que leas la publicación acerca de la sentencia if y cómo utilizarla en los Scripts de Bash.
La variable logged es revisada para saber si es cero o no.
Si es cero, el script imprimirá el mensaje y el script terminará su ejecución.
Si el usuario está logueado, la variable logged_on contendrá el nombre de usuario.
Revisando Si el Usuario puede Aceptar Mensaje
Para revisar si se permite la mensajería o no, utiliza el comando who con la opción -T.
1 2 3 4 5 6 7 8 9 10 11 | check=$(who -T | grep -i -m 1 $1 | awk '{print $2}') if [ "$check" != "+" ]; then echo "$1 disable messaging." echo "Exit" exit fi |
Puedes darte cuenta que utilizamos el comando who con -T. Esto muestra un (+) al lado del nombre de usuario si la mensajería está habilitada. De otra forma, muestra un (-), si la mensajería no está permitida.
Finalmente, revisamos buscamos un indicador de mensajería (-) si el indicador no está establecido en el signo de suma (+).
Revisando si el Mensaje fue Incluido
Pues revisar si el mensaje fue incluido o no de la siguiente manera:
1 2 3 4 5 6 7 8 9 | if [ -z $2 ]; then echo "Message not found" echo "Exit" exit fi |
Obtener el Terminal Actual
Antes de enviar un mensaje, nosotros necesitamos obtener la terminal actual y guardarla en una variable.
terminal=$(who | grep -i -m 1 $1 | awk '{print $2}')
Entonces podemos enviar el mensaje:
echo $2 | write $logged $terminal
Ahora podemos probar el script de shell complete para observar su resultado:
$ ./senderscript likegeeks welcome
Vamos a ver la otra ventana del shell:
¡¡Bien! Ahora puedes enviar mensajes simples de una palabra.
Enviar un Mensaje Largo
Si intentas enviar más de una palabra:
$ ./senderscript likegeeks welcome to shell scripting
No funciono. Solo se envió la primera palabra del mensaje.
Para arreglar este problema, utilizaremos el comando shift con el ciclo while.
1 2 3 4 5 6 7 8 9 | shift while [ -n "$1" ]; do message=$message' '$1 shift done |
Y ahora una cosa que necesita ser arreglada, lo cual es el parámetro del mensaje.
echo $whole_message | write $logged $terminal
Ahora el script completo es el siguiente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | #!/bin/bash logged=$(who | grep -i -m 1 $1 | awk '{print $1}') if [ -z $logged ]; then echo "$1 is not logged on." echo "Exit" exit fi check=$(who -T | grep -i -m 1 $1 | awk '{print $2}') if [ "$check" != "+" ]; then echo "$1 disable messaging." echo "Exit" exit fi if [ -z $2 ]; then echo "Message not found" echo "Exit" exit fi terminal=$(who | grep -i -m 1 $1 | awk '{print $2}') shift while [ -n "$1" ]; do message=$message' '$1 shift done echo $message | write $logged $terminal |
Si lo intentas nuevamente:
$ ./senderscript likegeeks welcome to shell scripting
¡¡Genial!! Function. De nuevo, no estoy aquí para hacer un script que envíe un mensaje al usuario, sino que mi meta principal es revisar nuestro conocimiento de scripting en shell y utilizar todo lo que hemos aprendido para ver cómo funciona todo junto.
Monitoreando el Espacio en Disco
Vamos a construir un script que monitoree los diez directorios más grandes.
Si añades la opción –s al comando du, mostrara totales resumidos.
$ du -s /var/log/
La opción –S es utilizada para mostrar el total de los subdirectorios.
$ du -S /var/log/
Deberías utilizar el comando sort para ordenar los resultados generados por el comando du para obtener los directorios más grandes de la siguiente manera:
$ du -S /var/log/ | sort -rn
La opción –n para ordenar numéricamente y la opción –r para ordenar en reversa, es decir, mostrar los números más grandes primero.
El comando N es utilizado para etiquetar cada línea con un numero:
1 2 3 | sed '{11,$D; =}' | sed 'N; s/\n/ /' | |
Luego formateamos un poco la salida utilizando el comando awk:
awk '{printf $1 ":" "\t" $2 "\t" $3 "\n"}'
Luego añadimos un símbolo de dos puntos y una tabulación para que aparezca mucho mejor.
1 2 3 4 5 6 7 8 9 10 11 12 13 | $ du -S /var/log/ | sort -rn | sed '{11,$D; =}' | # pipe the first result for another one to clean it sed 'N; s/\n/ /' | # formated printing using printf awk '{printf $1 ":" "\t" $2 "\t" $3 "\n"}' |
Supongamos que tenemos una variable llamada MY_DIRECTORIES que tienen 2 carpetas.
MY_DIRECTORIES=”/home /var/log”
Vamos a iterar sobre cada directorio de la variable MY_DIRECTORIES y obtiene el uso del disco utilizando el comando du.
Así que el script de shell se verá como a continuación:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #!/bin/bash MY_DIRECTORIES="/home /var/log" echo "Top Ten Directories" for DIR in $MY_DIRECTORIES; do echo "The $DIR Directory:" du -S $DIR 2>/dev/empty | sort -rn | sed '{11,$D; =}' | # pipe the first result for another one to clean it sed 'N; s/\n/ /' | # formated printing using printf awk '{printf $1 "\t" "\t" $2 "\t" $3 "\r\n"}' done exit |
¡¡Bien!! Ambos directorios /home y /var/log se muestran en el mismo reporte.
Tu puedes filtrar archivos, de manera que, en vez de calcular el consumo de todos los archivos, puedes calcular el consume de una extensión en especifica como *.log o cualquier otra.
Una cosa que tengo que mencionar aquí, en sistemas de producción, no puedes depender de un reporte del disco, en vez de eso se deben utilizar disk quotas.
El paquete quota es especializado para eso, pero aquí estamos aprendiendo solo cómo funcionan los scripts de bash.
De nuevo los scripts de shell que introducimos aquí son para mostrarte cómo funciona el scripting de shell, hay muchas maneras de implementar cualquier tarea en Linux.
Este es el final de mi publicación por ahora. Trate de reducir la extensión de la publicación tratando de mantener todo tan simple como fuese posible, espero que les haya gustado.
Vuelve pronto. Gracias.