File tests and metadata

Contents
The file test operators
Size and emptiness
stat
How old

The file test operators

A minus sign followed by a letter asks a question about a file and returns true or false. The letters are short but worth memorizing: they replace a whole library in other languages.

my $path = "/etc/hosts"; print "exists\n" if -e $path; print "regular\n" if -f $path; print "readable\n" if -r $path; print "executable\n" if -x $path;

perl demo.pl

exists
regular
readable

The full set covers directories with -d, symbolic links with -l, sockets with -S and ownership with -o. Use -e first when the answer decides whether a later test even makes sense.

Size and emptiness

Test -s returns the size in bytes, which is true for any non-empty file, and -z is true for an empty one. Both are handy before reading a file that a previous run should have filled.

my $path = "/etc/hosts"; my $size = -s $path; print "$size bytes\n" if $size; print "empty\n" if -z $path;

perl demo.pl

172 bytes

A missing file makes -s return undef and raise no warning, so treat a false result as missing or empty and check -e when the difference matters. The count itself is the size of your own /etc/hosts, so it changes from machine to machine.

stat

stat returns a thirteen-element list with everything the filesystem knows: device, inode, mode, link count, owner, group, size, and three timestamps. Named fields are easier to read than positions.

my $path = "/etc/hosts"; my @st = stat $path; print "size: $st[7]\n"; print "mode: ", sprintf("%04o\n", $st[2] & 07777);

perl demo.pl

size: 172
mode: 0644

The mode is printed in octal with the leading zero, the way chmod reads it. Field 7 is the size in bytes, the same number -s returns.

The File::stat module returns an object with named accessors instead: (stat $path)->size. Use it when the offsets look like line noise, which they will after a month away from the code.

How old

The -M operator returns the file age in days, measured from the start of the program. Together with -s it builds the classic cleanup filter.

The demo asks about a log file, so create a fresh app.log first:

printf 'INFO start\nERROR boom\n' > app.log

my $path = "app.log"; print "old log\n" if -M $path > 7; printf "%s is %.1f days old\n", $path, -M $path;

perl demo.pl

app.log is 0.0 days old

The seven-day test stays quiet, because the file was written a moment ago and its age is a fraction of a day. A log last touched two weeks back would print old log and report 14.0 days, which is exactly the filter a cleanup script needs.

The related tests are -A for last access and -C for inode change time. All three are cheap, because the information comes from the same stat call the kernel already made.

Next: Directories and paths

Article author: Arthur Isaev

Related articles
Perl
Perl course: zero to hero in 50 lessons
What is Perl and where it runs
Install Perl and check the version
Your first Perl script
The debugger as a REPL
Scalars and sigils
Numbers
Strings
Interpolation and quoting
Arrays
push, pop, shift and splice
Hashes
keys, values, exists and delete
Scalar and list context
Conditions and comparison
while, for, next and last
foreach and the default variable
Subroutines
Arguments in @_
References
Nested data structures
Regular expressions: match and anchors
Captures and named groups
Substitution with s///
split and join
grep and map
Sort and the Schwartzian transform
Read and write files
File tests and metadata
Directories and paths
die, warn and eval
Modules and Exporter
CPAN and cpanm
Objects with bless
Modern objects with Moo
Testing with Test::More
strict, warnings and diagnostics
Options with Getopt::Long
Environment and %ENV
system, backticks and pipes
One-liners with -n and -p
CSV and TSV processing
JSON with JSON::PP
HTTP clients with HTTP::Tiny
Sockets and IO::Socket
Databases with DBI
Capstone: todo CLI
Capstone: log report
Performance and profiling
Modern Perl tour
Hero roadmap: the whole course on one page
Install Perl on Windows 11
Install Perl on Ubuntu
Install Perl on Rocky Linux
Install Perl on macOS
Install Perl on FreeBSD
Perl in Docker

Search this site

Channel @aofeed Chat @aofeedchat

Contacts and cooperation:
I recommend our hosting beget.com
Write to info@aredel.com if you:
1. Want to write an article for our site or translate an article into your native language.
2. Want to place thematically relevant ads on the site.
3. Ads on my site pass maximum censorship. If you see an ad block unsuitable for school-age children, shocking or misleading - please contact us by e-mail
4. Found a mistake, inaccuracy, bug, etc. on the site. ... .......
5. Articles can be shared on social media by clicking a network icon: