Si el bucle no funciona según lo previsto para Perl scrpt

Si el bucle no funciona según lo previsto para Perl scrpt

Estoy intentando crear un script Perl que verifique automáticamente los cambios en una lista de datos cada hora, username/project/tota/datas/data.listes 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.listy 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.listGracias 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::SHAdesde CPAN, o probablemente ya esté empaquetado para tu distribución. En Debian, está en el libdigest-sha-perlpaquete.


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

información relacionada