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

Hello Monks

I am trying to monitor age of directory and alert if it is not modified in last two minutes. I have written following codes

#! /bin/usr/perl my $modified_within = 2 * 60; my $InputDir = "/tmp/KAKA/"; my $LastModified = (stat($InputDir)); my $CurrentTime = time; if ($LastModified->[9] > $CurrentTime - $modified_within) { print "Not Modified in last 2 minute"; } else { print "Modified in last 2 minutes"; }

Though ls -ltr shows that directory had no update since last 10 minute, i keep getting output Modified in last 2 minutes.

What is wrong with my code?

-KAKA

Replies are listed 'Best First'.
Re: Age of dir in UNIX
by marto (Cardinal) on Dec 04, 2013 at 16:47 UTC

    Read your if statement, you essentially say that if the last modified time of the directory is greater than 2 minutes ago, print "Not modified within last 2 minute". This is clearly not what you want to do. Here is a slightly tidied up version, see also File::stat which is a core module, and Basic debugging checklist.

    #!/bin/usr/perl use strict; use warnings; my $modified_within = 2 * 60; my $InputDir = "/home/marto/derpderp"; my $LastModified = (stat($InputDir))[9]; my $CurrentTime = time; if ( $LastModified > ($CurrentTime - $modified_within) ){ print "Modified in last 2 minutes\n"; }else{ print "Not Modified in last 2 minutes\n"; }

      Thank You for your response. This does not work as well. it is always goes into else part of IF

        I tested this on debian, creating new files/directories, running the code, waiting for a few minutes and running the code again. It worked every time. Try adding some debug statements, perhaps the values aren't what you expect them to be.

Re: Age of dir in UNIX
by choroba (Cardinal) on Dec 04, 2013 at 16:43 UTC
    You are calling stat in scalar context. As documented, it only returns success/failure, not the list. Possible fix: take directly the field you are interested in.
    my $LastModified = (stat $InputDir)[9];
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: Age of dir in UNIX
by Anonymous Monk on Dec 04, 2013 at 16:48 UTC

    Where did you get the code for getting the modified time, and the related test?

    As shown, the if condition will always fails ($LastModified value of 1, if stat() succeeds, is not an array, so array dereference will fail), so the else branch is taken.

    Only if strictness had been observed. :-/

      Correction. "[N]ot an array" in ...

      ... $LastModified value of 1, if stat() succeeds, is not an array, so array dereference will fail ...

      ... should have been "not an array reference".

Re: Age of dir in UNIX
by locked_user sundialsvc4 (Abbot) on Dec 04, 2013 at 17:26 UTC
    You should also be aware of this tidbit from man stat:
    Not all of the Linux filesystems implement all of the time fields.
    Some file system types allow mounting in such a way that file accesses do not cause an update of the st_atime field. (See 'noatime' in mount(8).)
      He's trying to access the mtime, not the atime. (mtime updates on every new/deleted/renamed file, AFAIK)
Re: Age of dir in UNIX
by taint (Chaplain) on Dec 04, 2013 at 17:32 UTC
    Greetings.

    While I'm not offering a complete solution. I think you might find this approach perhaps easier to follow.

    #!/usr/bin/perl -w use strict; my $arg1 = ('-XP . -type l -cmin'); my $arg2 = ('+15'); my $arg3 = ('xargs rm'); system("/usr/bin/find $arg1 $arg2 | $arg3");
    In this case, we're talking 15 minutes. And I clobber the file (xargs rm).
    You would probably want to replace -type l with -type d. Then modify $arg3 to perform the task you are looking to accomplish.

    Point being, you might find the command find a more reliable solution than stat.

    Modify for your own needs. :)

    HTH

    --Chris

    #!/usr/bin/perl -Tw
    use Perl::Always or die;
    my $perl_version = (5.12.5);
    print $perl_version;

      Thank You for reply. Unfortunately it is on HPUX and there is no -cmin or -mmin

      This is what shell aliases are for. More importantly, when going for a generic solution with find | xargs, one would be advised to make use of -print0 and -0 options:
        find ... -print0 | xargs -0 ...
      
      This serves to avoid "./nasty/surprises with spaces in file names /etc/fstab"