Perlスクリプトでループが期待どおりに機能しない場合

Perlスクリプトでループが期待どおりに機能しない場合

username/project/tota/datas/data.listファイルがあるdata.listの変更を毎時間自動的に確認し、残りのコードを実行するPerlスクリプトを作成しようとしています。私の場合は、行数を計算します。data.listCURLデータベースを使用してオンラインでアップロードします。

#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
}

CPANからインストールするか、Digest::SHAディストリビューションにパッケージとして含めることができます。 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

関連情報