Estoy intentando crear un script Perl que verifique automáticamente los cambios en una lista de datos cada hora, username/project/tota/datas/data.list
es donde está el archivo y luego ejecute los códigos restantes, que en mi caso, es contar el número de líneas en eso data.list
y cargarlo. usando CURL para la base de datos en línea.
#Look for changes every 6 hours
If (changes to data.list)
{
count number of lines,
upload data
}
else ( no change )
{
do nothing
}
Se realiza la parte en la que se cuentan líneas y se cargan datos. solo necesito encontrar una manera de buscar cambios automáticamente en data.list
Gracias a todos
Editado nuevo: recibí esta respuesta de cas,
use Digest::SHA qw(sha256_hex);
my $filename = 'username/project/tota/datas/data.list';
my $old_mtime = 0;
my $old_size = 0;
my $old_digest = '';
while(1) { # loop forever
my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
$atime, $mtime, $ctime, $blksize, $blocks) = stat($filename);
if ($mtime != $old_mtime || $size != $old_size) {
# slurp in entire file and get its sha256 hash
local $/;
open(my $fh, "<", $filename) or die "couldn't open $filename: $!\n";
my $digest = sha256_hex(<$fh>);
close($fh);
if ($digest ne $old_digest) {
print "change detected";
$old_digest = $digest;
$old_mtime = $mtime;
$old_size = $size
}
} else {
print "no change detected";
};
sleep 3600; # sleep 1 hour between iterations of the loop
}
El problema con esto es que cada vez que lo ejecuto, siemprecomenzar con el cambio detectadoy luego entrará en nocambio detectadocada hora, ¿alguna idea de cómo puedo cambiar esta parte?
Respuesta1
Si solo necesitas saberSIun archivo ha cambiado y no es necesario saberlo exactamenteQUÉha cambiado, la forma más sencilla es comparar un hash del archivo actual con un hash del archivo anterior.
Esto se puede optimizar aún más para evitar un costoso cálculo hash comparando primero las marcas de tiempo y los tamaños de los archivos.
por ejemplo, usando SHA256 deResumen::SHA:
use Digest::SHA qw(sha256_hex);
my $filename = 'username/project/tota/datas/data.list';
my $old_mtime = 0;
my $old_size = 0;
my $old_digest = '';
while(1) { # loop forever
my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
$atime, $mtime, $ctime, $blksize, $blocks) = stat($filename);
if ($mtime != $old_mtime || $size != $old_size) {
# slurp in entire file and get its sha256 hash
local $/;
open(my $fh, "<", $filename) or die "couldn't open $filename: $!\n";
my $digest = sha256_hex(<$fh>);
close($fh);
if ($digest ne $old_digest) {
# the file has changed. upload it
#....your curl upload code here...
# don't forget to update the old_* variables
$old_digest = $digest;
$old_mtime = $mtime;
$old_size = $size
}
} else {
# either the file hasn't changed or someone evil has modified it while
# making sure the file size and mtime remains the same.
# you'd need something like Digest::SHA to detect that :-)
};
sleep 3600; # sleep 1 hour between iterations of the loop
}
Puedes instalarlo Digest::SHA
desde CPAN, o probablemente ya esté empaquetado para tu distribución. En Debian, está en el libdigest-sha-perl
paquete.
No estoy seguro de por qué necesitas o quieres hacer esto en Perl. Si todo lo que quiere hacer es verificar si un archivo ha cambiado cada hora, entonces será mejor que simplemente ejecute un script de shell simple como el siguiente desde cron:
#!/bin/bash
# run this as "/path/to/script-name.sh /path/to/data.list"
filename="$1"
checksumfile='/var/tmp/data.list.sha256'
# cd to the directory containing data.list
cd "$(dirname "$filename")"
if [ ! -e "$checksumfile" ] || ! sha256sum --quiet -c "$checksumfile" ; then
# upload your file with curl
# ... your curl code here ...
# generate sha256 checksum file
sha256sum "$(basename "$filename")" > "$checksumfile"
# make sure it's RW by everyone
chmod a+rw "$checksumfile"
fi