如果循环未按 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
}

问题是每当我运行它时,它总是从检测到变化开始然后它会进入 no检测到变化每小时,知道如何更改这部分

答案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 中运行一个简单的 shell 脚本,如下所示:

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

相关内容