Página 1 de 1

Perl, Oracle, Net::Ftp y Digest::MD5

NotaPublicado: 2008-02-13 14:16 @636
por Arielinux
Buenas tardes, muchachos... tengo una consultilla.

En el otro topic puse el script para hacer el download de archivos que iban parametrizados por unas tablas en la DB Oracle.

Bueno, ahora el tema: está en cómo hacer para comparar el md5sum del archivo que está en el servidor ftp remoto y el archivo que ya bajé el día anterior, así sería una forma de controlar que si tienen el mismo md5sum que no baje el archivo para no duplicarlo.

¿Cómo podría revisar el md5sum del archivo del servidor ftp remoto?

Cualquier sugerencia es válida, desde ya gracias y saludos desde py.

NotaPublicado: 2008-02-13 14:18 @637
por Arielinux
Después voy a poner el código completo y más optimizado que el otro, que fue revisado por Uriel ;)

NotaPublicado: 2008-02-13 17:27 @769
por explorer
En principio, no se puede hacer, salvo que el servidor FTP permita la ejecución del comando md5sum por medio del envío del comando quot(), pero no veo claro cómo obtener la respuesta.

Yo lo que solía hacer es pedir un listado largo (con detalles) y comparaba tamaño en bytes y, sobre todo, las fechas. Si en el servidor era más moderno, lo bajaba.

NotaPublicado: 2008-02-16 10:57 @498
por explorer
Hay dos módulos nuevos en CPAN, que te podrían ser interesantes:

* Net::DownloadMirror
* Net::MirrorDir

NotaPublicado: 2008-02-18 06:32 @314
por Arielinux
Chas gracias... ahora los voy a revisar... lo que estaba pensando era bajar los archivos una vez y guardarlos en un directorio, y después al día siguiente, volverlos a bajar y hacer el md5sum desde el Linux contra los que están en el directorio, y así sucesivamente día a día...

NotaPublicado: 2008-02-18 17:52 @786
por explorer
Si el hecho de hacer el cálculo del md5 es por saber si han cambiado los ficheros, tanto en su contenido como en sus fechas de modificación, te valdría con hacer un dir() para saber si los tienes que bajar o no. No tendrías que bajar ningún fichero en caso de que no hubiese cambios.

NotaPublicado: 2008-02-20 08:41 @403
por Arielinux
¿Cómo usaría el dir() para hacer eso? Medió que no la cacho; si me podes dar una mano te agradecería...

NotaPublicado: 2008-02-20 11:35 @524
por explorer
Con el siguiente programa
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl -w
use strict;
use Net::FTP;

my $ftp = Net::FTP->new("servidor.ftp.com", Debug => 1)
      or die "ERROR: No puedo conectarme al servidor: $@";

$ftp->login('usuario','contraseña')
      or die "ERROR: No puedo hacer login: ", $ftp->message;

$ftp->cwd("public_html/cgi-bin")
      or die "ERROR: No puedo entrar en el directorio: ", $ftp->message;

my @ficheros = $ftp->dir();

print join "\n", @ficheros;
print "\n";
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4



obtengo el listado largo de los ficheros.

En mi servidor, me devuelve una línea por cada fichero, de este modo:
Código: Seleccionar todo
drwxrwxr-x   2 yo    users        4096 Nov 15  2006 My
-rwxr-xr-x   1 yo    users        5544 Oct  4 00:20 ajax_combo.pl
-rwxr-xr-x   1 yo    users         646 Nov 15  2006 clienteTable.pl
-rwxr-xr-x   1 yo    users         260 Aug 28  2006 comando.pl
-rwxr-xr-x   1 yo    users        1532 Feb  2  2007 fechas.pl


Como ves, están los campos separados por espacios.

Puedo ahora sacar las nombres, las fechas y los tamaños de los ficheros con un simple split:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my %ficheros;
chdir ("directorio de trabajo");
foreach ( @ficheros ) {
   
    my ( $nombre, $mes, $dia, $hora, $tamano ) = (split " ")[-1,-4,-3,-2,-5];
   
    # Comprobar si son iguales:
    # hacer un stat($nombre) para obtener la información del fichero local
    # si el $tamano o fecha es distinto, lo bajamos con un get().
    #
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Además, nos hemos colocado (chdir()) en el directorio donde están los ficheros locales. Para comprobar si tenemos que bajarlo o no, hacemos un stat() del fichero local y de todos los valores que nos devuelve, comparamos el tamaño y las fechas con el que está en el remoto. Con que uno solo de los valores sea distinto, nos lo bajamos.

Aquí hay un problema muy claro: esto fallará si no están sincronizados los relojes del cliente y del servidor. Si solo hay un segundo de diferencia, provocará que se bajen todos los ficheros, siempre. Una forma de solventarlo es haciendo diferencia de fechas: si el fichero que está en el servidor tiene más de... un día, por ejemplo, de diferencia con el local, entonces lo bajamos.

La mayor parte de las veces, bastaba con mirar el tamaño del fichero, porque suele cambiar con cada cambio de los ficheros, salvo en ficheros que siempre tienen el mismo tamaño (ficheros binarios que almacenan información siempre del mismo tamaño).

En CPAN hay más formas de hacer esto mismo. Por ejemplo, el script mirror.