Если цикл не работает так, как задумано для скрипта Perl

Если цикл не работает так, как задумано для скрипта Perl

Я пытаюсь создать скрипт Perl, который каждый час автоматически проверяет наличие изменений в data.list username/project/tota/datas/data.list(где находится файл), а затем выполняет оставшийся код, который в моем случае заключается в подсчете количества строк data.listи загрузке с помощью CURL в онлайн-базу данных.

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

Часть, в которой подсчитываются строки и загружаются данные, выполнена. Осталось только найти способ автоматического поиска изменений. data.listСпасибо всем.

Отредактировано новое: я получил этот ответ от 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
}

Проблема в том, что всякий раз, когда я его запускаю, он всегданачать с обнаруженного измененияи тогда это перейдет в неизменение обнаруженокаждый час, есть идеи, как я могу изменить эту часть?

решение1

Если вам нужно только знатьЕСЛИфайл изменился и не нужно знать точноЧТОизменился, самый простой способ — сравнить хэш текущего файла с хешем предыдущего файла.

Этот процесс можно дополнительно оптимизировать, чтобы избежать дорогостоящего вычисления хэша, предварительно сравнив временные метки файлов и размеры файлов.

например, используя SHA256 изДайджест::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
}

Вы можете установить Digest::SHAего с CPAN, или он, вероятно, уже упакован для вашего дистрибутива. В Debian он находится в libdigest-sha-perlпакете.


Я не уверен, зачем вам вообще нужно или хочется делать это в perl. Если все, что вам нужно, это проверять, изменился ли файл каждый час, то вам лучше просто запустить простой скрипт оболочки, например, такой, из 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

Связанный контент