I'm trying to create a Perl script that automatically check for changes in a data.list every hour, username/project/tota/datas/data.list
is where the file is and then execute the remaining codes, which in my case, is to count the number of lines in that data.list
and upload using CURL to online database.
#Look for changes every 6 hours
If (changes to data.list)
{
count number of lines,
upload data
}
else ( no change )
{
do nothing
}
The part whereby counting lines and uploading data is done. just need to find a way to automatically search for changes in data.list
Thanks all
Edited new : i got this answer from 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
}
problem with this is whenever i run it, it always start with change detected and then it will go into no change detected every hour, any idea how can i change this part
1 Answer 1
If you only need to know IF a file has changed and don't need to know exactly WHAT has changed, the easiest way is to compare a hash of the current file against a hash of the previous file.
This can be further optimised to avoid an expensive hash computation by first comparing file timestamps and file sizes.
e.g. using SHA256 from Digest::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
}
You can install Digest::SHA
from CPAN, or it's probably already packaged for your distro. On Debian, it's in the libdigest-sha-perl
package.
I'm not sure why you even need or want to do this in perl. If all you want to do is check if a file has changed every hour, then you'd be better off just running a simple shell script like the following from 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
-
not files, its the data.list , i want to see if there are more data added into that list every hourHelpMeAndroidStudio– HelpMeAndroidStudio2021年06月15日 06:01:49 +00:00Commented Jun 15, 2021 at 6:01
-
in that case, you can probably just use the file's timestamp and not bother with counting the lines. Do you need to upload the entire file again or just the changes?cas– cas2021年06月15日 06:10:15 +00:00Commented Jun 15, 2021 at 6:10
-
upload the entire data.list file again, im new at this , so im not sure how to doHelpMeAndroidStudio– HelpMeAndroidStudio2021年06月15日 06:34:01 +00:00Commented Jun 15, 2021 at 6:34
-
1. ask the sysadmins to install it for you. 2. if it's a personal script that's only going to be run by you, then install it into your home directory with
cpan Digest::SHA
cas– cas2021年06月15日 07:14:23 +00:00Commented Jun 15, 2021 at 7:14 -
cool buddy ! thanks for the help ! much appreciated, i am going to type out now on my linux and ttyHelpMeAndroidStudio– HelpMeAndroidStudio2021年06月15日 07:16:48 +00:00Commented Jun 15, 2021 at 7:16
data.list
to be able to spot the changes. Than rundiff --suppress-common-lines data.list.old data.list
. There are many parameters for diff that can help you customize the output to your preferences (e.g.--line-format
), In PERL, you can catch the output of diff and perform actions you need to.