Wenn die Schleife für das Perl-Skript nicht wie vorgesehen funktioniert

Wenn die Schleife für das Perl-Skript nicht wie vorgesehen funktioniert

Ich versuche, ein Perl-Skript zu erstellen, das automatisch stündlich nach Änderungen in einer Datenliste sucht, username/project/tota/datas/data.listwo sich die Datei befindet, und dann die verbleibenden Codes ausführt. In meinem Fall besteht das darin, die Anzahl der Zeilen darin zu zählen data.listund mithilfe von CURL in die Online-Datenbank hochzuladen.

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

Der Teil, in dem Zeilen gezählt und Daten hochgeladen werden, ist abgeschlossen. Ich muss nur noch einen Weg finden, automatisch nach Änderungen zu suchen. data.listDanke an alle

Neu bearbeitet: ich habe diese Antwort von cas bekommen,

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
}

das Problem dabei ist, dass jedes Mal, wenn ich es ausführe, es immerBeginnen mit erkannter Änderungund dann wird es in Nein gehenÄnderung erkanntjede Stunde, irgendeine Idee, wie ich diesen Teil ändern kann

Antwort1

Wenn Sie nur wissen müssenWENNeine Datei geändert wurde und Sie nicht genau wissen müssen,WASgeändert hat, besteht die einfachste Möglichkeit darin, einen Hash der aktuellen Datei mit einem Hash der vorherigen Datei zu vergleichen.

Dies kann weiter optimiert werden, um eine aufwändige Hash-Berechnung zu vermeiden, indem zuerst die Dateizeitstempel und die Dateigrößen verglichen werden.

zB mit SHA256 vonDigest::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
}

Sie können es von CPAN installieren Digest::SHA, oder es ist wahrscheinlich bereits für Ihre Distribution gepackt. Unter Debian ist es im libdigest-sha-perlPaket enthalten.


Ich bin mir nicht sicher, warum Sie das überhaupt in Perl tun müssen oder wollen. Wenn Sie nur stündlich prüfen möchten, ob sich eine Datei geändert hat, dann sollten Sie besser ein einfaches Shell-Skript wie das folgende von Cron ausführen:

#!/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

verwandte Informationen