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배포판에 패키지로 포함할 수 있습니다. 데비안에서는 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

관련 정보