Я пытаюсь создать скрипт 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