LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 08-10-2010, 09:30 AM   #1
BiFo
LQ Newbie
 
Registered: Aug 2010
Posts: 11

Rep: Reputation: 0
[Bash] MD5 Checks with Script.


Hi.
I'm triyng to make a Bash Script that checks (recursively) the MD5 from all the files in a certain directory and compare them against some other check that should be already done and saved in a file.
I've reached to the point where i have the MD5 from the file and the MD5 that the script saved in a file the last time it runs.
But, for some reason, when i compare them, the script always tell me that the MD5 change!
Here is the part of the script that make the comparision:
Code:
     for Archivo in $Archivos; do

	 # Run MD5SUM to the file and separe the MD5 and the PATH to make comparisions against the last archive i've generate with this script.
            Arch=`/usr/bin/md5sum $Archivo`
            FileMD5=`echo ${Arch%% *}`
            FilePath=`echo ${Arch##* }`

	# żDoes FilePath exist in the last file generated by this Script?
            Existe=`grep $FilePath $LogMasNuevo`
	    # The same: I separe the MD5 and PATH but for the line i took from the last file generated by this script.
            StatusFile=`echo ${Existe##* }`
            StatusMD5=`echo ${Existe%% *}`
            if [ $StatusFile == $FilePath ]; then
		# So the FilePath is the same... im gonna check the MD5 now.

                # To be sure, i remove from the MD5's all the spaces and line breaks...
                FileMD5=`echo $FileMD5 | sed 's/ //g'`
                StatusMD5=`echo $StatusMD5 | sed 's/ //g'`
                FileMD5=`echo -e $FileMD5 | tr -d '\n'`
                StatusMD5=`echo -e $StatusMD5 | tr -d '\n'`

		# żAre the MD5's different?
                if [ $StatusMD5 = $FileMD5 ]; then
                    echo "The MD5 change!"
                    echo $Arch >> $NewLogFile
                else
                    echo "Nothing to do..."
                fi

            else
                # The FilePATH is different, so its a new file!
                echo "The File $Arch " is new!"
                echo $Arch >> $NewLogFile
            fi
        done
For those who want it, the complete script: (Long and with Comments in Spanish!)
Code:
#!/bin/bash

#################################
## Inicio Seccion Configurable ##
#################################
# Historial de LOGs que deseamos almacenar.
HistoriaLogs=2
#################################
### Fin Seccion Configurable ####
#################################


# Funcion Generador de LOGs.
GenerarLogs () {
    PrimeraVes=$1
    echo "Creando Archivo de Log..."
    NewLogFile=$OldLogFile'-'$Fecha'.log'
    # Chequeo la correctitud del Nuevo Archivo de Log generado...
    #if [ "${NewLogFile:0:1}" = "." ]; then
    #   NewLogFile=${NewLogFile:1}
    #fi
    # Genero Listado de Archivos.
    Archivos=`find $Path -type f`
    # Verifico el Parametro, para analizar si es la primera ves que corro el script.
    if [ $PrimeraVes -eq 1 ]; then
        for Archivo in $Archivos; do
            MD5SUM=`/usr/bin/md5sum $Archivo`
            echo $MD5SUM  >> $NewLogFile
        done
    else
        # Busco el Ultimo LOG generado:
        declare -i MasAlto
        declare -i Actual
        Actual=0
        MasAlto=0
        ListadoDeLogs=`ls -1 $Dir`
        for Log in $ListadoDeLogs; do
            Actual=$(echo "$Log" | sed "s/[^0-9]//g")
            if [ $Actual -gt $MasAlto ]; then
                MasAlto=$Actual
            fi
        done
        LogMasNuevo=$OldLogFile'-'$MasAlto'.log'
        # Comienzo al creacion del Nuevo Log: Verifico por cada Archivo en mi arbol su status en el Ultimo LOG creado.

        declare -a Array
        declare -a Array2

        for Archivo in $Archivos; do
            Arch=`/usr/bin/md5sum $Archivo`
            FileMD5=`echo ${Arch%% *}`
            FilePath=`echo ${Arch##* }`
            Dash="'"
            Existe=`grep $FilePath $LogMasNuevo`
            StatusFile=`echo ${Existe##* }`
            StatusMD5=`echo ${Existe%% *}`
            # Verifico si el Archivo existia en el ultimo log.
            if [ $StatusFile == $FilePath ]; then
                # El Archivo Existe... Cambio su MD5?

                # Quitar Espacios...
                FileMD5=`echo $FileMD5 | sed 's/ //g'`
                StatusMD5=`echo $StatusMD5 | sed 's/ //g'`

                # Quitar Saltos de Linea...
                FileMD5=`echo -e $FileMD5 | tr -d '\n'`
                StatusMD5=`echo -e $StatusMD5 | tr -d '\n'`

                if [ $StatusMD5 = $FileMD5 ]; then
                    # Cambio su MD5 -> Una nueva version fue subida en la fecha de ultima modificacion.
                    echo "EL MD5 CAMBIO!"
                    echo $Arch >> $NewLogFile
                else
                    # Su MD5 se mantuvo identico -> No hubo cambios.
                    echo "Todo quedo Igual..."
                    echo $Arch >> $NewLogFile
                fi
            else
                # El Archivo no existe -> Se Subio un archivo nuevo!
                echo "EL ARCHIVO " $Arch " ES NUEVO!"
                echo $Arch >> $NewLogFile
            fi
        done
        # Finalizo verificando en base al ultimo LOG creado si al nuevo LOG recien creado le falta algo... Pudo haberse Eliminado un archivo!
        #cat $LogMasNuevo | while read line; do
        #    StatusFile=`echo ${line##* }`
        #    # Parseo la Linea y verifico solamente que el Path exista en el nuevo. Lo demas ya fue verificado antes.
        #    Existe=`grep $Dash$StatusFile$Dash $NewLogFile | wc -l`
        #    echo $Existe
        #    if [ $Existe -eq 0 ]; then
        #       # El archivo no existe -> Fue Eliminado!
        #       echo "EL ARCHIVO " $Linea " FUE ELIMINADO!"
        #    fi
        #done
    fi
}


# Parametros de Script.
Dir=`dirname $0`
File=`basename $0`

# Solo permito que se ingrese un unico parametro.
if [[ $# -lt 1 || $# -gt 1 ]]
then
    echo "Se requiere parametro: Directorio."
    exit
fi

Path=$1
# Verifico que exista el Directorio ingresado por Parametro.
if ! [ -d $Path ]; then
    echo "Error: $Path no es un Directorio existente en el sistema."
    exit
else
    # Chequeo que el Parametro (Directorio) ingresado contenga un "/" al final, de no contenerlo lo agrego.
    LastChar=${Path#${Path%?}}
    if ! [ $LastChar == "/" ]; then
        Path=$Path'/'
    fi
fi

# Seteo Formato de Fecha a AnioMesDiaHoraMinuto
Fecha=`date +%y%m%d%H%M`
# Chequeo si existe algun  archivo de LOG perteneciente a este Script (NombreDelScript-Fecha.log).
OldLogFile=$Dir'/'$File
# Chequeo la correctitud del Archivo de Log
if [ "${OldLogFile:0:2}" = "./" ]; then
    OldLogFile=${OldLogFile:2}
fi
# Cuento la cantidad de Archivos de LOG antiguos en la carpeta del Script.
declare -i CantidadLogs
CantidadLogs=`ls -1 $OldLogFile*'.log'| wc -l`

if [ $CantidadLogs -eq 0 ]; then
    echo 'Nota: El error "ls: VerificarVersiones.sh*.log: No such file or directory" es normal cuando no existen archivos de LOGs previos (Ej: El Script se corre por primera ves)'
    PrimeraVes=1
    # Genero el archivo de LOG avisando que no compare con otros LOGs antiguos.
    GenerarLogs $PrimeraVes
else
    PrimeraVes=0
    # Busco Archivo de LOG mas reciente...
    # Verifico que HistorialLogs sea un numero entero.
    if [ ! $(echo "$HistoriaLogs" | grep -E "^[0-9]+$") ]
    then
        echo "El parametro HistorialLogs debe ser un numero Entero. Verifique la seccion 'Configurable' del Script."
        exit
    fi
    # Verifico la cantidad de archivos de LOG sea menor que lo Configurado ("HistorialLogs").
    if [ $CantidadLogs -ge $HistoriaLogs ]; then
        Count=0
        # Debo Eliminar LOGs (los mas antiguos) hasta que tenga menos que la cantidad seteada mediante el parametro HistoriaLogs...
        declare -i MasBajo
        declare -i Actual
        declare -i LogSobrantes
        Actual=0
        LogSobrantes=$CantidadLogs-$HistoriaLogs
        while [ $Count -lt $LogSobrantes ]; do
            # Obtengo el LOG mas antiguo y lo Eliminio.
            ListadoDeLogs=`ls -1 $OldLogFile*'.log'`
            MasBajo=$Fecha
            for Log in $ListadoDeLogs; do
                Actual=$(echo "$Log" | sed "s/[^0-9]//g")
                if [[ $Actual -lt $MasBajo ]]; then
                    MasBajo=$Actual
                fi
            done
            rm -f $OldLogFile'-'$MasBajo'.log'
            Count=$[$Count+1]
        done
    fi
    # Genero el archivo de LOG avisando que debe comparar con el ultimo LOG que encuentre.
    GenerarLogs $PrimeraVes
fi
Sorry for my poor English,
Thanks in advance.
Bye!
 
Old 08-10-2010, 02:09 PM   #2
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
Can we see an example of the contents of your log file, the one designated by $LogMasNuevo? I think it might be key to figuring out your problem, because I don't see anything offhand to explain why it doesn't work (at least in the section you gave first, I haven't thoroughly looked at the full script yet).


In the meantime, I'd like to make a few general suggestions about your script.

1)
$(..) is highly recommended over `..` for embedded commands.

2)
Code:
FileMD5=`echo ${Arch%% *}`
FilePath=`echo ${Arch##* }`
The use of echo here is completely unnecessary (in addition to point one above). You can simply set the variables directly.
Code:
FileMD5=${Arch%% *}
FilePath=${Arch##* }
The same goes for the Status* variables and others.

3)
Code:
FileMD5=`echo $FileMD5 | sed 's/ //g'`
StatusMD5=`echo $StatusMD5 | sed 's/ //g'`
FileMD5=`echo -e $FileMD5 | tr -d '\n'`
StatusMD5=`echo -e $StatusMD5 | tr -d '\n'`
These can similarly be simplified by using parameter substitutions.
Code:
FileMD5=${FileMD5// }
FileMD5=${FileMD5//$'\n'}
StatusMD5=${StatusMD5// }
StatusMD5=${StatusMD5//$'\n'}
$'..' will expand escape sequences inside it into their literal characters, in this case the \n newline.

But as I read the code, these variables should never be anything but straight strings, so this step isn't really necessary. There are, however, many other places you could use parameter substitution in your script. You can use it instead of the dirname and basename commands, for example.

4)
Code:
if [ ! $(echo "$HistoriaLogs" | grep -E "^[0-9]+$") ]
If you use bash's extended test construct [[..]], you should be able to simplify this to something like:
Code:
if [[ ! "$HistoriaLogs" =~ ^[0-9]+$ ]]
..with =~ being a regex comparison. I haven't tested this with your script however.

In fact, I personally recommend using the extended test construct all the time. It can avoid a lot of hassles.
 
Old 08-10-2010, 09:03 PM   #3
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
you can do md5sum on all files
Code:
md5sum $Archivo/* 2>/dev/null
 
Old 08-11-2010, 06:54 AM   #4
BiFo
LQ Newbie
 
Registered: Aug 2010
Posts: 11

Original Poster
Rep: Reputation: 0
David, i've made the changes you mark me in my script. The articles are interesting.

An Example of the LOG File generated by the Script when i run it in the "/sysx/src/Nagios/Plugins/HP/" Directory:
Code:
f7407b3f175b3c566d0c89eeacae6571 /sysx/src/Nagios/Plugins/HP/check_hp-2.5.tar.gz
999e0dae644a3b04c6579f6306c47c9a /sysx/src/Nagios/Plugins/HP/check_hp-2.5/ChangeLog
8bc42d12ca51aa70125340813117cb62 /sysx/src/Nagios/Plugins/HP/check_hp-2.5/mibs/CPQ-SM2.mib
decdd0b6e792d7c697bc46acdfe30e86 /sysx/src/Nagios/Plugins/HP/check_hp-2.5/mibs/CPQ-SCSI.mib
735322c19406cbb7ba480c00f03c470c /sysx/src/Nagios/Plugins/HP/check_hp-2.5/mibs/CPQ-SINFO.mib
4234c85bd8a8264adb0b16fc2d4873c6 /sysx/src/Nagios/Plugins/HP/check_hp-2.5/mibs/CPQ-HLTH.mib
daddfb7178fe3e7325393024abb0b6ee /sysx/src/Nagios/Plugins/HP/check_hp-2.5/mibs/CPQ-IDA.mib
e22b86c39c8cf6de4d6c60f275624823 /sysx/src/Nagios/Plugins/HP/check_hp-2.5/mibs/CPQ-FCA.mib
34d37816de8de76ca1160fe7d498d0e9 /sysx/src/Nagios/Plugins/HP/check_hp-2.5/mibs/CPQ-RACK.mib
9941ae6af31848d72c7c5c787e116c41 /sysx/src/Nagios/Plugins/HP/check_hp-2.5/mibs/CPQ-CR.mib
b812be185046a6e6ace45fd8c87fce8c /sysx/src/Nagios/Plugins/HP/check_hp-2.5/mibs/CPQ-THRSH.mib
f3d2dc301bfa89a88db6bc51c64ec3b9 /sysx/src/Nagios/Plugins/HP/check_hp-2.5/mibs/CPQ-STSYS.mib
8b0816244fd6c6f1498ef0b269d4cc73 /sysx/src/Nagios/Plugins/HP/check_hp-2.5/mibs/CPQ-HOST.mib
58fa24fa6815d1bb741adcef14d62d84 /sysx/src/Nagios/Plugins/HP/check_hp-2.5/mibs/CPQ-NIC.mib
35948cfe90f5225f1d7b5826224b4a4f /sysx/src/Nagios/Plugins/HP/check_hp-2.5/mibs/CPQ-APPLIANCE.mib
e239f840655b9c6a15919eb58b650c54 /sysx/src/Nagios/Plugins/HP/check_hp-2.5/mibs/CPQ-STDEQ.mib
e4490e73427971ce2dfa01ccdc2ee8ef /sysx/src/Nagios/Plugins/HP/check_hp-2.5/mibs/CPQ-IDE.mib
60003f58cd204a3fe93003679f933697 /sysx/src/Nagios/Plugins/HP/check_hp-2.5/check_hp
0bdee27492cbc325e14d0159249ad436 /sysx/src/Nagios/Plugins/HP/check_hp-2.5/README
c2b3ea75f049cf133b1572a2e0299503 /sysx/src/Nagios/Plugins/HP/SIM/SIM_6.1_575369_003.bin
a15641584e0e409ce369e737ee6ece3e /sysx/src/Nagios/Plugins/HP/check_hparray.sh
63e9f32ff840860419d2f7849e4512ee /sysx/src/Nagios/Plugins/HP/check_hp_bladechassis-1.0.1.tar.gz
2d5fca0e9552bddb53dbadfc7be13429 /sysx/src/Nagios/Plugins/HP/check_insight_log.sh
beb0ba86a28c8cc070567eb5b88f4f7e /sysx/src/Nagios/Plugins/HP/check_hp_bladechassis-1.0.1/check_hp_bladechassis.php
7e0f7bcea187d9b181a51381adfdad9d /sysx/src/Nagios/Plugins/HP/check_hp_bladechassis-1.0.1/check_hp_bladechassis
b8f9db58f4371a4335ec58af6320ba39 /sysx/src/Nagios/Plugins/HP/check_hp_bladechassis-1.0.1/check_hp_bladechassis.pod
7a26b977d6133592dad37f3635019071 /sysx/src/Nagios/Plugins/HP/check_hp_bladechassis-1.0.1/check_hp_bladechassis.spec
5d0ad89078341c696ffa17990fa2b817 /sysx/src/Nagios/Plugins/HP/check_hp_bladechassis-1.0.1/CHANGES
9638db3d51bae432ed506cdc0d5fc304 /sysx/src/Nagios/Plugins/HP/check_hp_bladechassis-1.0.1/check_hp_bladechassis.8
952a2e0edaff31cd7e2f86326c147a22 /sysx/src/Nagios/Plugins/HP/check_hp_bladechassis-1.0.1/install.sh
b90f02719cde913531a3c7d25c641aa1 /sysx/src/Nagios/Plugins/HP/check_hp_bladechassis-1.0.1/INSTALL
d32239bcb673463ab874e80d47fae504 /sysx/src/Nagios/Plugins/HP/check_hp_bladechassis-1.0.1/COPYING
140758f4d68be3ed6c455ac8876d29db /sysx/src/Nagios/Plugins/HP/check_hp_bladechassis-1.0.1/README
Any idea where could be the problem?
 
Old 08-11-2010, 01:45 PM   #5
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
A-ha. It appears to be a simple mistake, easy to overlook:

Code:
# żAre the MD5's different?
if [ $StatusMD5 = $FileMD5 ]; then
     echo "The MD5 change!"
     echo $Arch >> $NewLogFile
else
     echo "Nothing to do..."
fi
According to this, if the MD5sums match, the files are different! You need to change this to "not equal".


A useful way to help debug a script is to add "-x" to the first line (#!/bin/bash -x), which makes it display all the behind the scenes substitutions. You can also turn it on and off inside the script with "set -x" and "set +x". There's also a "-v" option for even more verbose output.


By the way, it looks like my previous tip #4 above doesn't work here after all. The regex won't match single lines, and compares the input string as a whole. It would require a complex work-around to get it working right.
 
Old 08-17-2010, 06:08 AM   #6
BiFo
LQ Newbie
 
Registered: Aug 2010
Posts: 11

Original Poster
Rep: Reputation: 0
Hi!
I noticed the problem the other day and i today i've finished the script.
Here it is... (Readme & Comments in Spanish).

Code:
#!/bin/bash


##########
# README #
##########

# Explicacion #
# La primera ves que corre, este Script generara a partir del parametro (un directorio) enviado por el usuario un LOG de todos los archivos
# con sus respectivos MD5 dentro de ese arbol. A partir de ese momento, cuando se ejecute el Script subsiguientemente, realiza un chequeo general de los
# MD5 de todos los archivos dentro del arbol del directorio enviado por parametro enviado por el usuario contra el ultimo LOG que haya generado y
# generara Estadisticas respecto a Nuevos Archivos, Archivos Modificados y Archivos que ya existen en el directorio enviado por parametro en su ultima
# ejecucion.

# Notas #
# 1 - Modificar la "Seccion Configurable" del Script para adecuarla a nuestras nescesidades.
# 2 - Se recomienda utilizar valores altos en el parametro "LimiteEstadisticas" de la "Seccion Configurable" para evitar que el Script no almacene
#     cambios en las Estadisticas generadas.
# 3 - El script puede tomar un considerable tiempo de ejecucion si el Arbol de Directorios se modifico fuertemente y
#     las Estadisticas se han hecho excesivamente grandes.
# 4 - Solo se podra correr una ves por minuto como Maximo (A tener en cuenta si se utilizara un CRON).
# 5 - Podemos enviar los EMails con la herramienta "mail" o la herramienta "SMTPcli":
#     Por defecto se utilizara la herramienta "mail" (se asume que esta en /bin/mail, de no existir crearle un softlink -> "# ln -s ...").
#     Si deseamos utilizar la herramienta "smtp-cli", debemos ingresar la ruta completa en la "Seccion Configurable". De no estar bien especificado
#     el parametro "SMTPcli" entonces utilizara la herramienta "mail" para avisarnos que esta mal especificado el parametro mencionado.
#     Notar que la herramienta "smtp-cli" utiliza varias dependencias de PERL (El script no checara estas dependencias ni tampoco si el "smtp-cli"
#     enviar el correo exitosamente o falla por falta de dependencias. Asegurese de que funciona si desea utilizar la herramienta "smtp-cli".

# Errores Controlados #
# Para todos aquellos Errores que el Script sea capaz de detectar, los enviara por EMail.
# Errores InArreglables #
# (A) El Script NO funcionara correctamente con aquellos Archivos que tengan uno o mas espacios al FINAL de su nombre (Ej:"NombreArchivo ").


#################################
## Inicio Seccion Configurable ##
#################################
# Configuracion SMTP #
# Destinatario
To="FOlender@Coppel.com.ar"
# IP
IP="10.45.225.28"
# Si desea utilizar "smtp-cli" (http://www.logix.cz/michal/devel/smtp-cli/) para el envio de correos coloque a continuacion la ruta completa del mismo.
SMTPcli="/bin/smtp-cli"
# Remitente -> Solo aplica a smtp-cli.
From="FOlender@Coppel.com.ar"
# Puerto -> Solo aplica a smtp-cli.
Puerto=25

# Historial de LOGs a Almacenar #
# Cantidad de Archivos, debe ser mayor a 1.
HistoriaLogs=5
# Limite de estadisticas a Almacenar #
# Cantidad de Lineas, debe ser mayor a 9... (Aproximadamente: 15000=2.1 MBs)
LimiteEstadisticas=15000
#################################
### Fin Seccion Configurable ####
#################################



# Funcion que enviar Errores Controlados. Por Prolijidad, enviara un EMail por cada error que pudiese detectar.
EnviarError() {
    MiIP=`ifconfig  | grep 'inet addr:'| grep -v '127.0.0.1' | cut -d: -f2 | awk '{ print $1}'`
    Hostname=`hostname`
    Asunto="$Hostname ($MiIP) - ERROR: Controlador de Versiones."

    # Envio con "smtp-cli" o con "mail"?
    if [[ "$SMTPcli" ]]; then
        "$SMTPcli" --host=$IP --port=$Puerto --from=$From --to=$To --subject="$Asunto"  --body-plain="$Errores"  --missing-modules-ok
    else
        mail -s "$Asunto" "$To" < "$Errores"
    fi
    echo "Existen Errores en el Script. Revise su casilla de Correos"
    rm -f "$Errores"
    exit
}

# Funcion Generadora de Estadisticas.
AgregarEstadistica() {
    if ! [ -e "$Estadisticas" ]; then
        touch "$Estadisticas"
    fi
    declare -i Total
    # Agrego al inicio del Archivo...
    cat "$Estadisticas" > "$Tmp"
    echo -e $Informacion > "$Estadisticas"
    cat "$Tmp" >> "$Estadisticas"
    cat /dev/null > "$Tmp"
    echo -e "$Informacion" >> $Cuerpo
}

# Funcion Generadora de LOGs.
GenerarLogs() {
    PrimeraVes=$1
    NewLogFile="$OldLogFile"'-'$Fecha'.log'
    # Chequeo la correctitud del Nuevo Archivo de Log generado...
    #if [ "${NewLogFile:0:1}" = "." ]; then
    #   NewLogFile=${NewLogFile:1}
    #fi
    # Genero Listado de Archivos.
    # Chequeo que no exista el archivo NewLogFile antes de crearlo (si existe, es porque se corrio el Script multiples veces en un minuto).
    if [ -e "$NewLogFile" ]; then
        echo "El Archivo $NewLogFile ya existe! Por favor no intente ejecutar el Script mas de una ves por minuto." > "$Errores"
        rm -f "$Temporal"
        rm -f "$Tmp"
        rm -f "$Cuerpo"
        EnviarError
    fi
    find "$Path" -type f > "$Temporal"
    # Verifico el Parametro, para analizar si es la primera ves que corro el script.
    if [ $PrimeraVes -eq 1 ]; then
        while read line; do
            MD5SUM=`md5sum "$line" 2>> "$Errores"`
            echo $MD5SUM  >> "$NewLogFile"
        done < "$Temporal"
    else
        # Busco el Ultimo LOG generado:
        declare -i MasAlto
        declare -i Actual
        Actual=0
        MasAlto=0
        ListadoDeLogs=`ls -1 "$Dir"`
        for Log in $ListadoDeLogs; do
            Actual=$(echo "$Log" | sed "s/[^0-9]//g")
            if [ $Actual -gt $MasAlto ]; then
                MasAlto=$Actual
            fi
        done
        LogMasNuevo="$OldLogFile"'-'$MasAlto'.log'
        # Comienzo al creacion del Nuevo Log: Verifico por cada Archivo en mi arbol su status en el Ultimo LOG creado.

        while read line; do
            # Seteo el StatusFile en "/dev/null" para no arrastrar el anterior y asegurarme de que sino encuentro Matcheo, es porque es un archivo nuevo.
            StatusFile=/dev/null
            # Obtengo el MD5...
            Arch=`md5sum "$line" 2>>"$Errores"`
            FileMD5=${Arch%% *}
            FilePath=${Arch#* }
            # Elimino el primer espacio que se genera solo.
            FilePath=${FilePath:1}
            grep "$FilePath" "$LogMasNuevo" > "$Tmp"
            # El resultado del grep podria devolver varios matcheos no exactos (incluso con "-w") por lo que busco el exacto recorriendolos todos.
            while read line; do
                #Exacto=`echo $line | awk '{print $2}'`
                Exacto=${line#* }
                if [ "$Exacto" == "$FilePath" ]; then
                    StatusFile=${line#* }
                    StatusMD5=${line%% *}
                    # Si ya encontre lo que buscaba del grep, dejo de leer el archivo.
                    break;
                fi
            done < "$Tmp"
            rm -f "$Tmp"

            # Verifico si el Archivo existia en el ultimo log (Ya verificado, pero mas efectivo que colocar el resto del script dentro del while anterior!).
            if [ "$StatusFile" == "$FilePath" ]; then
                # El Archivo Existe... Cambio su MD5?
                if [ "$StatusMD5" = "$FileMD5" ]; then
                    # Su MD5 se mantuvo identico -> No hubo cambios.
                    echo $Arch >> "$NewLogFile"
                else
                    # Cambio su MD5 -> Una nueva version fue subida en la fecha de ultima modificacion.
                    ExistenModificaciones=1
                    UltimaModificacion=`date -r $StatusFile +%F' '%R`
                    Informacion=`date`"\t Nuevo MD5 (Modificado) -> \t "$UltimaModificacion" \t "$StatusMD5" \t "$StatusFile
                    AgregarEstadistica $Informacion
                    echo $Arch >> "$NewLogFile"
                fi
            else
                # El Archivo no existe -> Se Subio un archivo nuevo!
                ExistenModificaciones=1
                UltimaModificacion=`date -r $FilePath +%F' '%R`
                Informacion=`date`"\t Nuevo Archivo (Subido) -> \t "$UltimaModificacion" \t "$FileMD5" \t "$FilePath
                AgregarEstadistica $Informacion
                echo $Arch >> "$NewLogFile"
            fi
        done < "$Temporal"
        # Finalizo verificando en base al ultimo LOG creado si al nuevo LOG recien creado le falta algo... Pudo haberse Eliminado un archivo!
        while read line; do
            Existe=0
            StatusFile=`echo ${line#* }`
            # Parseo la Linea y verifico solamente que el Path exista en el nuevo. Lo demas ya fue verificado antes.
            grep "$StatusFile" "$NewLogFile" > "$Tmp"
            # El resultado del grep podria devolver varios matcheos no exactos (incluso con "-w") por lo que busco el exacto recorriendolos todos.
            while read line; do
                Exacto=${line#* }
                if [ "$Exacto" == "$StatusFile" ]; then
                    Existe=1
                    # Si ya encontre lo que buscaba del grep, dejo de leer el archivo.
                    break;
                fi
            done < "$Tmp"
            rm -f "$Tmp"
            if [ $Existe -eq 0 ]; then
                # El archivo no existe -> Fue Movido o Eliminado!
                ExistenModificaciones=1
                Informacion=`date`"\t Eliminado o Movido -> \t\t\t\t\t "$StatusMD5" \t "$StatusFile
                AgregarEstadistica
            fi
        done < "$LogMasNuevo"
    fi
    rm -f "$Temporal"
}


# Parametros de Script.
Dir=`dirname "$0"`
File=`basename "$0"`

# Path Completo, sin importar desde donde corra el script, donde se generara el archivo temporal a utilizar.
if [ "${Dir:0:2}" = "." ]; then
    Temporal="temporal"
    Tmp="Tmp"
    Cuerpo="Cuerpo.txt"
    Estadisticas="Estadisticas.log"
    Errores="Errores.log"
else
    Temporal="$Dir/temporal"
    Tmp="$Dir/tmp"
    Cuerpo="$Dir/Cuerpo.txt"
    Estadisticas="$Dir/Estadisticas.log"
    Errores="$Dir/Errores.log"
fi
# Vacio los archivos temporales que utilizare, para asegurarme de que no tenian nada extranio!
cat /dev/null > "$Tmp"
cat /dev/null > "$Temporal"
cat /dev/null > "$Cuerpo"
cat /dev/null > "$Errores"

# Solo permito que se ingrese un unico parametro.
if [[ $# -lt 1 || $# -gt 1 ]]
then
    echo "Se requiere parametro: Directorio." &> "$Errores"
    EnviarError
fi

Path=$1
# Verifico que exista el Directorio ingresado por Parametro.
if ! [ -d "$Path" ]; then
    echo "Error: $Path no es un Directorio existente en el sistema." &> "$Errores"
    EnviarError
else
    # Chequeo que el Parametro (Directorio) ingresado contenga un "/" al final, de no contenerlo lo agrego.
    LastChar=${Path#${Path%?}}
    if ! [ $LastChar == "/" ]; then
        Path="$Path"'/'
    fi
fi

# Verifico si SMTPcli esta definida.
if [[ $SMTPcli ]]; then
    # Salvo algunos casos en que el parametro esta mal seteado pero imagino que intento decir...
    if [[ "$SMTPcli" = "."  ]] || [[ "$SMTPcli" = "./" ]] || [[ "$SMTPcli" = "./smtp-cli" ]] || [[ "$SMTPcli" = ".smtp-cli" ]]; then
        SMTPcli=$Dir"/smtp-cli"
    fi
    if ! [ -f "$SMTPcli" ]; then
        echo "Error: El parametro 'SMTPcli' colocado en la 'Seccion Configuarble' no es valido." > "$Errores"
        # Seteo SMTPcli en Null nuevamente, para enviar con "mail" la notificacion de error!
        SMTPcli=
        rm -f "$Tmp"
        rm -f "$Temporal"
        rm -f "$Cuerpo"
        EnviarError
    fi
fi

# Asumo que desde el principio no existen cambios, si dps cambia algo, modifico esta variable.
declare -i ExistenModificaciones
ExistenModificaciones=0

# Seteo Formato de Fecha a AnioMesDiaHoraMinuto
Fecha=`date +%y%m%d%H%M`

OldLogFile="$Dir"'/'"$File"
# Chequeo la correctitud del Archivo de Log
if [ "${OldLogFile:0:2}" = "./" ]; then
    OldLogFile="${OldLogFile:2}"
fi
# Cuento la cantidad de Archivos de LOG antiguos en la carpeta del Script.
declare -i CantidadLogs
CantidadLogs=`ls -1 "$OldLogFile"*'.log' 2> /dev/null | wc -l`

if [ $CantidadLogs -eq 0 ]; then
    PrimeraVes=1
    # Genero el archivo de LOG avisando que no compare con otros LOGs antiguos.
    GenerarLogs $PrimeraVes
else
    PrimeraVes=0
    # Busco Archivo de LOG mas reciente...
    # Verifico que HistorialLogs sea un numero entero.
    if [ ! $(echo "$HistoriaLogs" | grep -E "^[0-9]+$") ]; then
        echo "El parametro HistoriaLogs debe ser un numero Entero. Verifique la seccion 'Configurable' del Script." &> "$Errores"
        rm -f "$Tmp"
        rm -f "$Temporal"
        rm -f "$Cuerpo"
        EnviarCorreo
    fi
    if [ $HistoriaLogs -lt 2 ]; then
        echo "El parametro HistoriaLogs debe ser mayor o igual a 2. Verifique la seccion 'Configurable' del Script." &> "$Errores"
        rm -f "$Tmp"
        rm -f "$Temporal"
        rm -f "$Cuerpo"
        EnviarCorreo
    fi
    # Verifico la cantidad de archivos de LOG sea menor que lo Configurado ("HistorialLogs").
    if [ $CantidadLogs -ge $HistoriaLogs ]; then
        Count=0
        # Debo Eliminar LOGs (los mas antiguos) hasta que tenga menos que la cantidad seteada mediante el parametro HistoriaLogs...
        declare -i MasBajo
        declare -i Actual
        declare -i LogSobrantes
        Actual=0
        LogSobrantes=$CantidadLogs-$HistoriaLogs
        while [ $Count -le $LogSobrantes ]; do
            # Obtengo el LOG mas antiguo y lo Eliminio.
            ls -1 "$OldLogFile"*".log" > "$Tmp"
            MasBajo=$Fecha
            while read line; do
                Actual=$(echo "$line" | sed "s/[^0-9]//g")
                if [[ $Actual -lt $MasBajo ]]; then
                    MasBajo=$Actual
                fi
            done < "$Tmp"
            rm -f "$OldLogFile"'-'"$MasBajo"'.log'
            Count=$[$Count+1]
        done
    fi
    # Genero el archivo de LOG avisando que debe comparar con el ultimo LOG que encuentre.
    GenerarLogs $PrimeraVes
fi

# Si existieron Modificaciones, reconstruyo el archivo de Estadisticas y envio el EMail correspondiente.
if [ $ExistenModificaciones -eq 1 ]; then
    # Limpio todas las lineas que tengan mi encabezado en las Estadisticas.log
    cat /dev/null > "$Tmp"
    Encabezado=`echo -e "Fecha \t\t \t\t Estado \t\t\t Modificacion \t\t MD5 \t\t\t\t\t Path"`
    String="-----------------------------------------------------------------------------------------------------------------------------"
    while read line; do
        if ! [ "$line" = "$Encabezado" ] && ! [ "$line" = "$String" ] ; then
            echo -e "$line" >> "$Tmp"
        fi
    done < "$Estadisticas"
    # Agrego nuevamente mi encabezado al inicio.
    echo -e "Fecha \t\t \t\t Estado \t\t\t Modificacion \t\t MD5 \t\t\t\t\t Path" > "$Estadisticas"
    echo $String >> "$Estadisticas"
    cat "$Tmp" >> "$Estadisticas"
    rm -f "$Tmp"

    # Verifico que LimiteEstadisticas sea Entero.
    if [ ! $(echo "$LimiteEstadisticas" | grep -E "^[0-9]+$") ]
    then
        echo "El parametro LimiteEstadisticas debe ser un numero Entero. Verifique la seccion 'Configurable' del Script." &> "$Errores"
        rm -f "$Tmp"
        rm -f "$Temporal"
        rm -f "$Cuerpo"
        EnviarCorreo
    fi
    if [ $LimiteEstadisticas -lt 10 ]; then
        echo "El parametro LimiteEstadisticas debe ser mayor o igual a 10. Verifique la seccion 'Configurable' del Script." &> "$Errores"
        rm -f "$Tmp"
        rm -f "$Temporal"
        rm -f "$Cuerpo"
        EnviarCorreo
    fi
    # Verifico que no me pase del Tamanio Maximo para las estadisticas...
    Tamanio=`cat "$Estadisticas" | wc -l`
    if [ $Tamanio -ge $LimiteEstadisticas ]; then
        # Reescribo las estadisticas salteando las ultimas "$Total" lineas del archivo.
        Total=$LimiteEstadisticas-1
        head -n $Total "$Estadisticas" > "$Tmp"
        cat "$Tmp" > "$Estadisticas"
    fi

    # Envio de correos.
    MiIP=`ifconfig  | grep 'inet addr:'| grep -v '127.0.0.1' | cut -d: -f2 | awk '{ print $1}'`
    Hostname=`hostname`
    Asunto="$Hostname ($MiIP) - Controlador de Versiones."
    # Limpio el Cuerpo de mi Mensaje
    cat "$Cuerpo" > "$Tmp"
    echo -e "Fecha \t\t \t\t Estado \t\t\t Modificacion \t\t MD5 \t\t\t\t\t Path" > "$Cuerpo"
    echo $String >> "$Cuerpo"
    cat "$Tmp" >> "$Cuerpo"
    # Envio con "smtp-cli" o "mail"?
    if [[ "$SMTPcli" ]]; then
        "$SMTPcli" --host=$IP --port=$Puerto --from=$From --to=$To --subject="$Asunto"  --body-plain="$Cuerpo"  --missing-modules-ok
    else
        mail -s "$Asunto" "$To" < "$Cuerpo"
    fi
fi

# De existir Errores controlados en el Script, los envio por EMail...
if [ -s "$Errores" ]; then
    MiIP=`ifconfig  | grep 'inet addr:'| grep -v '127.0.0.1' | cut -d: -f2 | awk '{ print $1}'`
    Hostname=`hostname`
    Asunto="$Hostname($MiIP) - ERROR: Controlador de Versiones."
    # Envio con "smtp-cli" o "mail"?
    if [[ "$SMTPcli" ]]; then
        "$SMTPcli" --host=$IP --port=$Puerto --from=$From --to=$To --subject="$Asunto"  --body-plain="$Errores"  --missing-modules-ok
    else
        mail -s "$Asunto" "$To" < "$Errores"
    fi
    echo "Existen Errores en el Script. Revise su casilla de Correos"
    rm -f "$Errores"
    rm -f "$Tmp"
    rm -f "$Cuerpo"
    exit
fi

# Elmino archivos Temporales.
rm -f "$Errores"
rm -f "$Tmp"
rm -f "$Cuerpo"

echo "El Script finalizo exitosamente."

exit
Thanks for your help!

Bye.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
bash script that checks authentication failures and sends mail panoskan Programming 4 06-06-2009 05:24 PM
Bash script thats checks for faild login attempts. k1piee Programming 4 02-11-2009 09:46 PM
Ubuntu Hardy fails md5 checks (debsums) for modules... Akonbobot Linux - Security 7 11-13-2008 09:13 AM
Help trying to troubleshoot MD5 bash script mcdrr Programming 6 01-09-2008 02:36 AM
Script that checks mapsize objorkum Linux - Software 1 07-06-2005 11:42 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 03:23 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration