¿Requieres de una instalación o configuración de Linux o sus servicios?
¿Un desarrollo WEB empresarial a la medida?
¿Un curso o capacitación a la medida?
Revisa el sitio de SERVICIOS de LinuxTotal


Script que muestra que equipos estn usando shares de Samba 

Copyright © 2005-2024 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.



¿Requieres de una instalación o configuración de Linux o sus servicios?
¿Un desarrollo WEB empresarial a la medida?
¿Un curso o capacitación a la medida?
Revisa el sitio de SERVICIOS de LinuxTotal

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.


Dona a través de paypal::


O a través de bitcoins:


14TNQv5wM3xkSv65gHGQ6s6f8yTZuFTohE
Más artículos de LinuxTotal

Linux es un sistema multiusuario, por lo tanto, la tarea de añadir, modificar, eliminar y en general administrar usuarios se conv....


Linux ofrece multitud de servicios o servidores, estos pueden iniciar o arrancar junto con la carga del sistema o pueden después ....


En casi todas las distribuciones de Linux se instala por defecto el excelente programa para manipulación de imágenes ImageMagick....


La siguiente combinación de comandos te permite extraer los 10 comandos más usados directamente del historial (comando history) ....


Una tarea administrativa algo común, es eventualmente tener que añadir un nuevo disco duro (IDE) al o a los que ya se tienen, de....


La más simple definición de un proceso podría ser que es una instancia de un programa en ejecución (corriendo). A los procesos....


El directorio /proc es una bestia extraña. Realmente no existe, sin embargo puedes explorarlo. Sus archivos de tamaño 0 no son n....


vi es el venerable y confiable editor de texto que encontrarás en TODAS las distintas versiones, distribucciones, sabores de Linu....


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....


En este tutorial sobre listas de control de acceso en squid, aprenderás lo básico de como configurarlas y establecerlas en la co....



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