Preface
I wrote a script that can check multiple simulation log files at the same time and generate html tables. Sort files from newest to oldest by modification time. Then I have been unable to use the stath function to obtain ctime.
Conclusion: The find function will change the current directory where the program is executed , find(\&process_files, $dir);
and the function is run in the $dir directory .
text
The directory structure of the test environment is as follows:
.
├── check_logs.pl
└── logs
├── 1.txt
├── 2.txt
└── 3.txt
1 directory, 4 files
1. Use the built-in function stat
Perl provides a built-in function stat() to obtain file-related information, and the function returns an array.
Official documentation introduces stat - Perldoc browser
my($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks) = stat($file_name);
Introducing some of the more important meanings:
- $dev and $ino
- The number of the device where the file is located and the inode number of the file.
- $mode
- A collection of permission bits for a file, along with other bits of information. The lower 9 bits are the Linux permission bits.
- $nlink
- The number of hard links to the file or directory.
- $uid and $gid
- Numeric representation of the user ID and group ID of the file owner
- $size
- File size in bytes
- $atime, $mtime and $ctime
- Three timestamps, a 32-bit integer representing the number of seconds since 1970.
- Access time (atime): The access time records the last time the file was read. Whenever a file is read, its access timestamp is updated. This can be useful for certain applications, such as log auditing or tracking how often a file is accessed.
- Modification time (mtime): The modification time records the last time the file content was modified. When a file's content (data) is modified, its modification timestamp is updated. This is useful for determining when a file was last modified.
- Change time (ctime): The change time records the last time the file metadata was changed. Metadata is non-data information related to a file, such as the file's permissions, owner, or file type. When these metadata properties change, their change timestamps are updated.
Let’s first look at the code that uses the built-in function to get the modification time.
#! /bin/perl -w
use strict;
use warnings;
use File::Find;
use File::Basename;
my $time = (stat("./logs/1.txt"))[10];
print "$time\n";
The running results are as follows:
[fengbh@VM-16-14-centos perl_stat]$ ./check_logs.pl
1703579691
2. Use File::stat
File::stat will override the built-in system function, which provides functions similar to the built-in function stat in a class manner.
Official Documentation File::stat - by-name interface to Perl's built-in stat() functions - Perldoc Browser
The code to obtain the modification time using a class is as follows:
#! /bin/perl -w
use strict;
use warnings;
use File::Find;
use File::stat;
my $time = stat("./logs/1.txt")->mtime;
print "$time\n";
The running results are as follows:
[fengbh@VM-16-14-centos perl_stat]$ ./check_logs.pl
1703579691
3. Use in File::Find
This is implemented using built-in functions.
#! /bin/perl -w
use strict;
use warnings;
use File::Find;
my $dir = "./logs";
find(\&process_files, $dir);
sub process_files{
return if !-f $_;
#debug
print "\$_ = $_\n";
print "\$File::Find::name = $File::Find::name\n\n";
#get mtime
my $mtime = (stat($File::Find::name))[10];
die "Can't stat file;$!\n" if !defined($mtime);
# debug
print "mtime = $mtime\n";
}
operation result:
[fengbh@VM-16-14-centos perl_stat]$ ./check_logs.pl
$_ = 3.txt
$File::Find::name = ./logs/3.txt
Can't stat file;No such file or directory
When running, an error is reported and the file cannot be found. But the file pathname passed to the stat function is correct.
This is because the find function will change the current directory where the program is executed , or it can be understood that the process_files function is run in the $dir directory .
This is the reason for the error. $File::Find::name is the path relative to the initial execution directory, and $_ is the path relative to $dir.
Modify the code to:
#! /bin/perl -w
use strict;
use warnings;
use File::Find;
my $dir = "./logs";
find(\&process_files, $dir);
sub process_files{
return if !-f $_;
#debug
print "\$_ = $_\n";
print "\$File::Find::name = $File::Find::name\n\n";
#get mtime
my $mtime = (stat($_))[10];
die "Can't stat file;$!\n" if !defined($mtime);
# debug
print "mtime = $mtime\n";
}
The execution results are as follows:
[fengbh@VM-16-14-centos perl_stat]$ ./check_logs.pl
$_ = 3.txt
$File::Find::name = ./logs/3.txt
mtime = 1703577429
$_ = 1.txt
$File::Find::name = ./logs/1.txt
mtime = 1703579691
$_ = 2.txt
$File::Find::name = ./logs/2.txt
mtime = 1703577426
The execution result is correct
references
- Official documentation introduces stat - Perldoc browser
- Official Documentation File::stat - by-name interface to Perl's built-in stat() functions - Perldoc Browser
- "Introduction to Perl Language"