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

相關內容