http://www.perlmonks.org?node_id=378255

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

Hi,
I am running a perl script as follows:
##BEGIN CODE &setup_command(); #setup command of 3rd party script to run &run_command(); #Run 3rd party script. script generates #file.log my $logfile = "file.log"; if (-M "$logfile" > 0) { print "The logfile generated by 3rd party script is not new\n"; exit(1); } ##END CODE
The -M file test operator above always turns True and exits, even though the logfile is newly generated. I beleive that this could be due to the mtime not being refreshed and hence the error. I get this error whether a previous logfile exists or if the logfile is newly created. Any suggestions as to how this problem could be rectified is welcome. Thanks, Bayruds

20040728 Edit by ysth: adjust code tags to only span code

Replies are listed 'Best First'.
Re: -M file test operator
by graff (Chancellor) on Jul 29, 2004 at 02:52 UTC
    Hi Bayruds,

    First, a quick note about formatting your posts: put "<code>" and "</code>" at the beginning and end of perl code -- not including paragraphs of text (use plain old html tags like <P>, <UL>, etc to format your text). It's easy to get to Writeup Formatting Tips -- take a look at that.

    Second, how about you try one more diagnostic: create a junk file (or locate such a file that already exists), and give the path/name of that file as a command line arg to this little script:

    #!/usr/bin/perl print "-M of $ARGV[0] is ".(-M $ARGV[0]).$/; # should be positive system("touch $ARGV[0]"); # reset file's mod time to now. sleep 1 print "-M of $ARGV[0] is now ".(-M $ARGV[0]).$/; # should be (very sma +ll) negative sleep 4; print "-M of $ARGV[0] is now ".(-M $ARGV[0]).$/; # should be equal to +previous
    If the outputs disagree with the comments, you might have a deep problem -- you may need to report which OS you're using, and which perl version. (Maybe even what sort of hardware you have.)

    You seem to be doing the right sort of test (-M>0), so it could still be one of those cases where you really believe that you're checking the right file (the same one that the 3rd party thing created), and that the file is new, etc, when in fact...

    update: fixed link

Re: -M file test operator
by beable (Friar) on Jul 29, 2004 at 00:40 UTC
    Hello Baryuds, I wrote the following program to try to reproduce your problem, but I wasn't able to. I'd suggest you add a line like this to your program, so you can see just how big a number -M is returning:

    print "minus M returns: ", (-M $logfile), "\n";

    #!/usr/bin/perl use strict; use warnings; my $logfile = "file.log"; my $internal = 0; if ($internal) { # create a logfile open LOGFILE, ">$logfile" or die "can't open $logfile: $!"; print LOGFILE "This is a test\n"; close LOGFILE or die "can't close $logfile: $!"; } else { # create logfile externally system("./write-log"); } # sleep? sleep 3; print "minus M returns: ", (-M $logfile), "\n"; # test modification time if (-M $logfile > 0) { print "The logfile generated by 3rd party script is not new\n"; exit(1); } else { print "It's a new logfile! Hoooray!\n"; } __END__
      Hi Beable I ran it a couple of times, These are the values I got: # Using $mtime = (-M $logfile); MTIME: 1.15740740740741e-05 MTIME: 0.000104166666666667 Thanks for your reply. bayruds

        Hi Bayruds, here is a program to find out how old the log file actually is. It turns out that we are talking about 1 to 9 seconds old. Is that too old for you? If that seems like a reasonable age, I'd suggest you change your "-M" test line to something like:

        # see if the file is more than about one hour old if (-M $logfile > 0.042) { ... }

        Here's the program. Somebody will probably produce a one-liner to do this now.

        #!/usr/bin/perl use strict; use warnings; my $secs_per_day = 60 * 60 * 24; while (my $line = <DATA>) { chomp $line; if ($line =~ m/MTIME:\s+(.*)/) { my $time = $1; my $secs = $time * $secs_per_day; print "$time days is $secs second(s)\n"; } } __END__ Output: 1.15740740740741e-05 days is 1 second(s) 0.000104166666666667 days is 9.00000000000003 second(s) __DATA__ MTIME: 1.15740740740741e-05 MTIME: 0.000104166666666667
Re: -M file test operator
by ysth (Canon) on Jul 29, 2004 at 02:33 UTC
    Is the logfile on a networked drive of a computer with a slightly out-of-sync system time? Suggest you just check (stat($logfile))[9] before and after running the 3rd party script and just see if it changes. You aren't messing with $^T, are you?