Se o loop não funcionar como pretendido para script perl

Se o loop não funcionar como pretendido para script perl

Estou tentando criar um script Perl que verifica automaticamente alterações em um data.list a cada hora, username/project/tota/datas/data.listé onde está o arquivo e depois executa os códigos restantes, que no meu caso, é contar o número de linhas nele data.liste fazer o upload usando CURL para banco de dados online.

#Look for changes every 6 hours
If (changes to data.list)
{
   count number of lines,
   upload data
}
else ( no change )
{
 do nothing
}

A parte em que é feita a contagem de linhas e o upload dos dados. só preciso encontrar uma maneira de procurar alterações automaticamente em data.listObrigado a todos

Editado novo: recebi esta resposta do 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
}

problema com isso é sempre que eu executo, semprecomeçar com alteração detectadae então ele entrará em nãoalteração detectadaa cada hora, alguma ideia de como posso mudar essa parte

Responder1

Se você só precisa saberSEum arquivo foi alterado e não precisa saber exatamenteO QUEmudou, a maneira mais fácil é comparar um hash do arquivo atual com um hash do arquivo anterior.

Isso pode ser otimizado ainda mais para evitar um cálculo de hash caro, comparando primeiro os carimbos de data e hora dos arquivos e os tamanhos dos arquivos.

por exemplo, usando SHA256 deResumo::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
}

Você pode instalar Digest::SHAa partir do CPAN ou provavelmente já está empacotado para sua distribuição. No Debian, está no libdigest-sha-perlpacote.


Não sei por que você precisa ou deseja fazer isso em Perl. Se tudo o que você deseja fazer é verificar se um arquivo é alterado a cada hora, é melhor executar um script de shell simples como o seguinte no 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

informação relacionada