Script que muestra que equipos están usando shares de Samba 

Copyright © 2005-2017 LinuxTotal.com.mx
Se concede permiso para copiar, distribuir y/o modificar este documento siempre y cuando se cite al autor y la fuente de linuxtotal.com.mx y según los términos de la GNU Free Documentation License, Versión 1.2 o cualquiera posterior publicada por la Free Software Foundation.

Autor: Sergio González D.  
***** ESTE ES UN ARTÍCULO YA OBSOLETO. *****

Este artículo me lo publicó originalmente en inglés el sitio linux.com

Uno de mis clientes tiene múltiples aplicaciones basadas en VisualBasic 6 y como base de datos Access, que se ejecutan directamente en un servidor Linux con Samba a través de shares (recursos o directorios compartidos en el servidor) y en los clientes que son WindowsXP, unidades de red que apuntan a los shares de samba. El problema está en que Access bloquea la base de datos y cuando necesita hacer una actualización, necesita buscar cuál de los 100 (mas o menos) usuarios es que esta utilizando la aplicación. Asi que aunque sea un solo usuario el que este usando el programa, necesita (o necesitaba) tomar el teléfono y marcar varias extensiones hasta encontrar al "culpable" pedirle que se saliera de la aplicación, subir la actualización al servidor.

Claro, la mejor solución en este caso es que cambié de Microsoft Access a MySQL. Implica cambiar la conexión a la base de datos en VisualBasic6, quizás ajustar el método de conexión (de DAO a ADO) para un mejor rendimiento, etc. pero el resultado serán aplicaciones más sólidas y estables y sin el problema del bloqueo de la base de datos cuando se requiere actualizarla o compactarla o repararla (ya conocen Access).

Pero mientras hace lo anterior, una combinación de programas de Linux pueden ayudarte a determinar quien en la red esta usando recursos compartidos en cualquier momento, permitiéndote decirle al o a los usuarios que se salgan del sistema (de la unidad de red) mientras actualizas el sistema.

Entonces, hice un script para resolver el problema. Usando una combinación de lsof, netstat, gawk, grep, uniq y otras utilerías del bash shell. Todos los ejecutables de las aplicaciones están almacenados en /usr/apps y en subcarpetas nombradas 'nomina', 'contabilidad', 'ventas', etc. Asumiendo por ejemplo que se requiere saber todas las direcciones IP de los usuarios que están usando el sistema de nómina, se usa lsof (list open files) que lista los archivos abiertos.

#> lsof  |  grep /usr/apps/nomina
smbd      16258  systems  cwd   DIR        8,5     4096    2191586 /usr/apps/nomina
smbd      16258  systems  27rR  REG        8,5  2449408    2191760 /usr/apps/nomina/nomina.exe
smbd      16258  systems  28u   REG        8,5 37883904    1684790 /usr/apps/nomina/dbnomina.mdb
smbd      16258  systems  29uw  REG        8,5      256    1684290 /usr/apps/nomina/dbnomina.ldb
smbd      19237  systems  cwd   DIR        8,5     4096    2191586 /usr/apps/nomina
smbd      19237  systems  25rR  REG        8,5  2449408    2191760 /usr/apps/nomina/nomina.exe
smbd      19237  systems  27u   REG        8,5 37883904    1684790 /usr/apps/nomina/dbnomina.mdb
smbd      19237  systems  28uw  REG        8,5      256    1684290 /usr/apps/nomina/dbnomina.ldb
smbd      19237  systems  29rW  REG        8,5    45056    1684863 /usr/apps/nomina/report1.rpt

lsof listaría varias decenas de líneas de archivos abiertos, asi que con grep filtramos solo aquellas líneas que tienen el patrón buscado '/usr/apps/nomina'. En este caso, la salida muestra que Samba (smbd) tiene varios archivos abiertos, y que son los procesos PID 16258 y 19237, aqui ya se puede apreciar que dos usuarios son los que están usando el archivo 'nomina.exe'. También observamos que la última línea muestra que el archivo 'reporte1.rpt' esta siendo usado, esta es una extensión típica de Crystal reports, asi que se deduce que también está aplicación esta tmbién ocupada. Sin embargo, el listado previo aun no nos muestra que usuarios los están utilizando. Asi que extraemos solo lo necesario de lo anterior que son los números de proceso (PID).

#> lsof  |  grep /usr/apps/payroll | gawk '{ print $2 }'
16258
16258
16258
16258
19237
19237
19237
19237
19237

Con gawk, es posible indicar que solo se requiere el segundo campo. Pero no necesitamos todas esas repeticiones, asi que ahora concateno el comando uniq, el cual permite remover líneas duplicadas de una lista ordenada:

lsof  |  grep /usr/apps/payroll | gawk '{ print $2 }' | uniq
16258
19237

Ahora, se envía el resultado a un archivo temporal:

#> lsof | grep /usr/apps/payroll | gawk '{ print $2 }' | uniq > tmp

A continuación, hay que relacionar esos números de procesos PIDs con un socket de red, usando el comando netstat con la opción -p. netstat mostrará el PID y el nombre del programa al que el socket pertenece, por ejemplo:

#> netstat -p | grep 16258
tcp        0      0 192.168.100.250:netbios-ssn   192.168.100.32:1028 

La cuarta columna (192.168.100.250:netbios-ssn) es el servidor donde se alojan las palicaciones y la quinta columna (192.168.0.32:1028) es la dirección IP y el número de puerto del equipo cliente, el dato que se esta buscando!!.

Asi que ahora ponemos todo junto en un script que leera los PIDs del archivo 'tmp' temporal.

lsof | grep /usr/apps/payroll | gawk '{ print $2 }' | uniq > tmp
echo "EQUIPOS USANDO LA APLICACIÓN:"
while read renglon ; do
   netstat -p | grep $renglon | gawk '{ print $5 }' | cut -d":" -f1
done < tmp

La línea netstat -p | grep $row | gawk '{ print $5 }' | cut -d":" -f1 primero ejecuta netstat después llama a grep con la variable $renglon, que viene de cada renglón del archivo 'tmp'. Extrae la quinta columna con gawk, entonces con cut y el delimitador ':' indicado por -d, extrae el primer campo que es efectivamente la dirección IP.

Se le da al sript un nombre (script.sh por ejemplo), se cambian sus permisos a digamos chmod 700 script.sh para hacerlo ejecutable. Y cuando lo ejecutes el resultado será algo como lo siguiente:

./script.sh
EQUIPOS USANDO LA APLICACIÓN:
192.168.100.32
192.168.100.78

Bien, ya está funcionando, ya podemos ver quien esta conectado en este momento usando la nómina, pero sería mejor se pudieramos saber a quien pertenece la IP, asi que basta con que modifiquemos el archivo /etc/hosts donde añadiremos una línea por cada IP de nuestra red, seguido del nombre del usuario, algo como lo siguiente:

127.0.0.1 localhost 192.168.100.32 Lindsay_Hayek 192.168.100.78 Salma_Lohan 192.168.100.145 Tom_Norton 192.168.100.193 Edward_Cruise

La línea de 'localhost' no debes eliminarla. Y se añade un grep adicional para que el resultado de la línea netstat sea el argumento a buscar dentro de /etc/hosts:

grep - w `netstat -p | grep $row | gawk '{ print $5 }' | cut -d":" -f1` /etc/hosts

Nótese que la línea original está entre comillas graves ` ` o también llamadas backticks, el argumento -w sirve para buscar concordancias exactas, asi '192.168.0.13' solo buscará esa IP y no '192.168.0.132'.

Sin embargo, si el script encuentra una IP que por no se haya añadido a /etc/hosts, mandará un error en vez de simplemente imprimir la dirección IP. Para resolver este pequeño problema, lo resulevo con una sentencia if. Si la instrucción previa es correcta (se sabe que es correcta cuando regresa un 0 a través de la variable '$?'), entonces el script imprime IP-usuario y continua al siguiente renglón dentro del archivo 'tmp', y cualquier cosa aparte de 0 indicará que la dirección IP no se encontró dentro de /etc/hosts, asi que solo se imprime la IP. Para saber quien es el usuario, pues tendremos que consultar con el administrador de la red o alguna lista de relación IP-usuario. EL script entonces queda algo como lo siguiente:

lsof | grep /usr/apps/nomina | gawk '{ print $2 }' | uniq > tmp
echo "EQUIPOS USANDO LA APLICACIÓN:"
while read renglon ; do
   grep -w `netstat -p | grep $renglon | gawk '{ print $5 }' | cut -d":" -f1` /etc/hosts
   
   if [ $? -ne 0 ]; then
     netstat -p | grep $renglon | gawk '{ print $5 }' | cut -d":" -f1
   end if
   
done < tmp

En el if se evalua la expresión que quiere decir si '$?' es diferente '-ne' de 0 entonces solo imprime la IP.

Si se ejecuta de nuevo el script, el resultado podría ser lo siguiente:

#> ./script.sh
EQUIPOS USANDO LA APLICACIÓN:
192.168.100.32    Lindsay_Hayek
192.168.100.78    Salma_Lohan
192.168.100.90

Por último, podemos mejorar el script aun más. Ya que en la primera línea donde dice '/usr/apps/nomina' tenemos que estar cambiando 'nomina' a algo más cada vez que deseamos buscar por otra aplicación, entonces podemos sustituirla por lo siguiente:

lsof | grep /usr/apps/$1 | gawk '{ print $2 }' | uniq > tmp
echo "EQUIPOS USANDO LA APLICACIÓN $1:"

Donde '$1' es un argumento de script.sh que se indica en la línea de comandos, y al ejecutarlo entonces sería de la siguiente manera:

#> ./script.sh contabilidad
EQUIPOS USANDO LA APLICACION contabilidad:
192.168.100.145    Tom_Norton
192.168.100.178
192.168.100.193    Edward_Cruise

Hay ciertamente otras maneras de lograr lo anterior, espero que este ejemplo te sirva para entender mejor los shell scripts en Linux.


LinuxTotal en:

Si encuentras útil la información que proveé LinuxTotal, considera realizar un donativo que estimule a seguir proporcionando contenido de calidad y utilidad. Gracias.

Más artículos de LinuxTotal

awk o la versión GNU gawk es más que un simple comando de procesamiento de patrones, es todo un lenguaje de análisis semántico....


En el artículo de LinuxTotal.com.mx sobre permisos se explica lo que es un archivo con permisos SUID o SGID, pueden ser potencial....


Entre los administradores de sistemas Linux es común el término 'one liners', algo asi como 'los de una línea', y se refiere a ....


Muchos validadores de direcciones de correo electrónico devolverán errores cuando se enfrenten con una inusual pero válida dire....


Uno de mis clientes tiene múltiples aplicaciones basadas en VisualBasic 6 y como base de datos Access, que se ejecutan directamen....


Ya no es nada raro que un centro de cómputo o en un site se encuentren varios sistemas Linux actuando como servidores de archivos....


En este archivo de configuración se indica el modo en que los mensajes del sistema son bitacorizados a través de la utileria sys....


Cuando usas rm para eliminar o borrar un archivo, lo que realmente sucede es que los datos del archivo, su información tal cual, ....


El comando find de Linux es extremadamente potente. No hay nada mejor para hacer todo tipo de búsquedas de archivos y carpetas qu....


Hay ocasiones que los usuarios insisten en poner contraseñas muy débiles de 5 o 6 caracteres a lo más. Y el argumento que dan e....



Copyright © LinuxTotal.com.mx 2006-2017
info@linuxtotal.com.mx · linuxtotal.com.mx@gmail.com