snorky has asked for the wisdom of the Perl Monks concerning the following question:

First time using stat()command. I get unexpected results.
Here is the code:
while($loopnum <10) { $loc=(telldir(backups)); $newloc=seekdir(backups,($loc++)); $filename=readdir(backups); ($size,$mtime)=stat($filename); $convtime=localtime($mtime); print($filename, " is " ,$size, " bytes long, last modified on ", +$mtime," ",$convtime,"\n"); $loopnum++; }

returns:

. is 2308 bytes long, last modified on 218105879 Mon Nov 29 00:57:59 1976
.. is 2308 bytes long, last modified on 128 Wed Dec 31 16:02:08 1969
scripts.tgz is 2308 bytes long, last modified on 218105914 Mon Nov 29 00:58:34 1976
users.tgz is 2308 bytes long, last modified on 218105915 Mon Nov 29 00:58:35 1976
20050303.log is 2308 bytes long, last modified on 219200296 Sat Dec 11 16:58:16 1976
20050304.log is 2308 bytes long, last modified on 219200298 Sat Dec 11 16:58:18 1976
20050304.tgz is 2308 bytes long, last modified on 219200299 Sat Dec 11 16:58:19 1976
20050305.tgz is 2308 bytes long, last modified on 219200302 Sat Dec 11 16:58:22 1976
20050306.log is 2308 bytes long, last modified on 219200305 Sat Dec 11 16:58:25 1976
20050307.log is 2308 bytes long, last modified on 219200307 Sat Dec 11 16:58:27 1976

The dates and file sizes are wrong.
20050302.tgz is the backup for 2005-Mar-02; all the other files are named using the same convention.

The size of 20050304.tgz is approximately 973795939; all the other .tgz files are about the same size.

The .log files are always 70 bytes.

Replies are listed 'Best First'.
Re: bad results from stat()
by Paladin (Vicar) on Mar 07, 2005 at 23:45 UTC
    If you look at the docs for stat you will see that the first 2 elements returned from it are not the file size and mtime, but the device and inode numbers of the files. The perldoc for stat shows you which elements are returned in which order. You probably want something like:
    ($size,$mtime)=(stat($filename))[7,9];
Re: bad results from stat()
by kvale (Monsignor) on Mar 07, 2005 at 23:45 UTC
    Usually stat is called like so:
    ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, $atime,$mtime,$ctime,$blksize,$blocks) = stat( $filename);
    From there you can use the $size and $mtime values. See perldoc -f stat for more information.

    -Mark

Re: bad results from stat()
by ysth (Canon) on Mar 07, 2005 at 23:51 UTC
    Size and mtime are the 8th and 10th items returned by stat. Try ($size,$mtime) = (stat($filename))[7,9]; See perldoc -f stat or perldoc perlcheat
Re: bad results from stat()
by jpeg (Chaplain) on Mar 07, 2005 at 23:47 UTC
    Are you sure that $size and $mtime aren't the device number and inode of the files?

    perldoc -f stat

    says it returns an array consisting of a lot more than size and mtime. If you want just those two attributes, I'd do
    my @statinfo = stat($filename); my $size = $statinfo[7]; my $mtime = $statinfo[9];
    perldoc -f stat for more info. Hope this helps.
    --
    jpg
      I have 3 books on Perl (but not the Camel book). They all dance around the important part of the topic. Now I understand what's going on (thanks to all of you who answered). So the part about stat() returning an array, and specifying which elements from the array I need to call, makes perfectly good sense. Thanks, Monks PS: I don't have the Camel book because 1. a former employer has it (grrrr) 2. I only use PERL when the task needs PERL's awesome power.
        We understand ;)

        By the way, perldoc is perl's online help and is installed with perl. It's a fantastic reference and easy to use. At a command prompt type:

        perldoc -f stat or any function name for info about the function and what args it expects and what it returns,
        perldoc perlop to decipher all of those funky operators,
        perldoc perlsyn
        perldoc perlref
        perldoc perlfaq
        are all worth looking at as well.
Re: bad results from stat()
by chb (Deacon) on Mar 08, 2005 at 08:10 UTC
    You could even use the core module File::stat to access the field by name. See perldoc File::stat and use something along these lines (untested):
    use File::stat; $st = stat($file) or die "No $file: $!"; printf "Size: %d, mtime: %d", $st->size(), localtime($st->mtime());