newbie01.perl has asked for the wisdom of the Perl Monks concerning the following question:

Hi Perl gurus, Just want to know what improvement can be done with the code below if any. I am sure a lot of improvement/changes is required. I will be calling this script from a UNIX script, i.e.timediff=`timediff.pl $file`, so $file will be passed to the Perl script. It's probably a good idea to check whether the $file is passed and if so, check if the file exists or not.

Most of the print lines are just for testing/purposes. Ultimately, what am wanting to assign to the timediff variable in the UNIX script is the string "( 5 weeks, 3 days, 10:16:1 )" but only if the file is x days old. Do I need to have something like a return timediff_detail command in the Perl script?

FYI, I've decided to use stat instead of Perl Date modules because each server have different Date modules installed, some have Date::Manip, some have Date::Calc etc. so using stat is the best option that I have.

Any advise/help will be much appreciated. Thanks.

----- Code for timediff.pl so far ----- #!/usr/bin/perl #$today = localtime(); $today_epoch = time(); $today = localtime($today_epoch); @date_fields = split(" ",$today); $day=$date_fields[2]; $month=uc($date_fields[1]); $year=$date_fields[4]; @time_fields = split(":",$date_fields[3]); $hour=$time_fields[0]; $minute=$time_fields[1]; $second=$time_fields[2]; print "Today is ==> $today \n"; print "DAY is ==> $day ... \n"; print "MONTH is ==> $month ... \n"; print "YEAR is ==> $year ... \n"; print "HOUR is ==> $hour ... \n"; print "MINUTE is ==> $minute ... \n"; print "SECOND is ==> $second ... \n"; my ( $dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks ) = stat("x1.pl"); print "\n"; print "< ====================================== > \n"; print "Output from stat ... \n"; print " dev => $dev \n"; print " ino => $ino \n"; print " mode => $mode \n"; print " nlink => $nlink \n"; print " uid => $uid \n"; print " gid => $gid \n"; print " rdev => $rdev \n"; print " size => $size \n"; print " atime => " . localtime($atime) . " ==> \n"; print " mtime => " . localtime($mtime) . " ==> \n"; print " mtime - not localtime => " . $mtime . " ==> \n"; print " ctime => " . localtime($ctime) . " ==> \n"; print " blksize => $blksize \n"; print " blocks => $blocks \n"; print "< ====================================== > \n"; print "\n"; $difference=$today_epoch-$mtime; $seconds = $difference % 60; $difference = ($difference - $seconds) / 60; $minutes = $difference % 60; $difference = ($difference - $minutes) / 60; $hours = $difference % 24; $difference = ($difference - $hours) / 24; $days = $difference % 7; $weeks = ($difference - $days) / 7; print "Age of x1.pl is: \n"; print "( $weeks weeks, $days days, $hours:$minutes:$seconds ) \n"; print "\n"; exit 0; -------------- Sample Output: -------------- Today is ==> Fri Mar 11 02:56:22 2011 DAY is ==> 11 ... MONTH is ==> MAR ... YEAR is ==> 2011 ... HOUR is ==> 02 ... MINUTE is ==> 56 ... SECOND is ==> 22 ... < ====================================== > Output from stat ... dev => 84148225 ino => 7975633 mode => 33248 nlink => 1 uid => 103 gid => 101 rdev => 0 size => 629 atime => Fri Mar 11 01:07:26 2011 ==> mtime => Mon Jan 31 16:40:21 2011 ==> mtime - not localtime => 1296445221 ==> ctime => Thu Feb 10 19:09:46 2011 ==> blksize => 8192 blocks => 8 < ====================================== > Age of x1.pl is: ( 5 weeks, 3 days, 10:16:1 )
  • Comment on More actions 1 of 50 Older › Date arithmetic advise/improvement - using stat ... calling the Perl script from a UNIX script
  • Download Code

Replies are listed 'Best First'.
Re: More actions 1 of 50 Older › Date arithmetic advise/improvement - using stat ... calling the Perl script from a UNIX script
by Eliya (Vicar) on Mar 10, 2011 at 16:26 UTC
    what am wanting to assign to the timediff variable in the UNIX script is the string "( 5 weeks, 3 days, 10:16:1 )" but only if the file is x days old. Do I need to have something like a return timediff_detail command

    You could print the string to STDOUT and then capture it in the shell script via backticks (what you're doing already, actually).  (return is not for passing info from one process to another — if that's what you meant.)

    As for assigning it only if it's x days old: you could "return" an empty string if it's not x days old, assign that to a temp variable first, and only copy the temp variable to the timediff variable if it's not empty. E.g.

    #!/bin/sh timediff=foo tmpret=`timediff.pl $file` if [ "$tmpret" != "" ] ; then # empty? timediff=$tmpret fi echo $timediff
Re: More actions 1 of 50 Older › Date arithmetic advise/improvement - using stat ... calling the Perl script from a UNIX script
by Neighbour (Friar) on Mar 11, 2011 at 09:34 UTC
    Also, you could use the "find" commando (if available in your environment, but typically so in all linuxes) to only process files older than X days:
    find /search_in_here/ -type f -mtime +X