Estou tentando criar um script Perl que verifica automaticamente alterações em um data.list a cada hora, username/project/tota/datas/data.list
é onde está o arquivo e depois executa os códigos restantes, que no meu caso, é contar o número de linhas nele data.list
e fazer o upload usando CURL para banco de dados online.
#Look for changes every 6 hours
If (changes to data.list)
{
count number of lines,
upload data
}
else ( no change )
{
do nothing
}
A parte em que é feita a contagem de linhas e o upload dos dados. só preciso encontrar uma maneira de procurar alterações automaticamente em data.list
Obrigado a todos
Editado novo: recebi esta resposta do 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
}
problema com isso é sempre que eu executo, semprecomeçar com alteração detectadae então ele entrará em nãoalteração detectadaa cada hora, alguma ideia de como posso mudar essa parte
Responder1
Se você só precisa saberSEum arquivo foi alterado e não precisa saber exatamenteO QUEmudou, a maneira mais fácil é comparar um hash do arquivo atual com um hash do arquivo anterior.
Isso pode ser otimizado ainda mais para evitar um cálculo de hash caro, comparando primeiro os carimbos de data e hora dos arquivos e os tamanhos dos arquivos.
por exemplo, usando SHA256 deResumo::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
}
Você pode instalar Digest::SHA
a partir do CPAN ou provavelmente já está empacotado para sua distribuição. No Debian, está no libdigest-sha-perl
pacote.
Não sei por que você precisa ou deseja fazer isso em Perl. Se tudo o que você deseja fazer é verificar se um arquivo é alterado a cada hora, é melhor executar um script de shell simples como o seguinte no 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