Perl Script to check file date and size

Hi guys, i am new to perl. I started reading the perl documents and try to come up with some logic.

I am trying to create a script that would go into a location, search for todays files, then searches for all .txt files from today.

If todays not found, its an error

If file size is less than 0kb, its an error

It should email me the results. Here is the code so far:

#!/usr/local/bin/perl
use strict;
use vars qw(%opt);
use vars qw(%logfiles);
use Data::Dumper;
use Carp;

my $foundmymessages;
my $errormymessages;

sub StartUp () {
   my $todaydate = `/location1/select.pl -0`; chomp $todaydate;
   my ($YYYY, $MM, $DD) = unpack("A4A2A2", $todaydate);
   my $yesterday = `/location1/seclect.pl -1`; chomp $yesterday;
   my ($YYYYY, $YMM, $YDD) = unpack("A4A2A2", $yesterday);
   $opt{TodayDate} = $todaydate;
   $opt{YYYY} = $YYYY;
   my ($foo,$YY) = unpack("A2A2", $YYYY);
   $opt{YY} = $YY;
   $opt{MM} = $MM;
   $opt{DD} = $DD;
   $opt{YYYYY} = $YYYYY;
   $opt{YMM} = $YMM;
   $opt{YDD} = $YDD;
   $opt{Error} = 0;
   $opt{EqualDelim}="========================================================================";
   $opt{DashDelim}="--------------------------------------------------------------------------";
} # end StartUp

sub Standby () {
   %logfiles = (
        'Location1' => "/loc/loc-01/logs/ser/Feed/TC`date '+%m%d%Y'`*.txt",
        'Location2' => "/loc/loc-02/logs/ser/Feed/TC`date '+%m%d%Y'`*.txt",
        'Location3' => "/loc/loc-03/logs/ser/Feed/TC`date '+%m%d%Y'`*.txt",
        'Location4' => "/loc/loc-04/logs/ser/Feed/TC`date '+%m%d%Y'`*.txt",        
    );

} # end Standby


sub scanLogs () {
   foreach my $logfileinstance (sort keys %logfiles) {
      my $lfile = "$logfiles{$logfileinstance}";
      

     

} # end scanLogs

So, is your script not working? Are you seeing any particular errors?

I am trying to build the logic to do the checks. I have not run the script yet as I know its not complete.

another approach - here is a bare bones perl example using stat, time functions and directory functions.

Unless you are doing this to learn perl, I would suggest a two line shell script using the unix find command, maybe like this:

#!/bin/ksh
# $1 == /path/to/files
 touch -t $(date +'%y%m%m0000') ./dummy
 find $1 -newer ./dummy -size +0 -name '*.txt'  > /dev/null
 exit $?

perl:

#!/usr/bin/perl -w 
sub checkfile{

      $today = time;
      $today -= $today % 86400;  # midnight in epoch seconds
      $return_value = 0;
                                    #  mtime in epoch seconds
      $mtime = (stat("$_[0]"))[9] || die "cannot stat file $!";  
      $size =  (stat("$_[0]"))[7];  # size in bytes
      $ok = "not ok";
      
      if( $size > 0 && $mtime >= $today )
      {
            $ok = "ok"; 
            $return_value = 1;           
      }
      print "$_[0] is $ok\n";
      return $return_value;
}

$found = 0;
opendir (DIRHNDL, "$ARGV[0]") ||  die "Cannot open directory $!";
@filelist = readdir (DIRHNDL);
closedir (DIRHNDL);

foreach $filename ( @filelist )
{
   if ($filename =~ /txt$/)
   {
     $found |= checkfile $filename;
   }
}
print "return status = $found\n";

exit 0;

Hi jim mcnamara, I have a simple and stupid question to ask you..

in your perl example.. where do the directory location go? is it like this:

opendir (DIRHNDL, '/location1/locat/*.txt' "$ARGV[0]") ||  die "Cannot open directory $!";

No. put the code in an executable file, call it myfile.pl

./myfile.pl /path/to/nowhere

where /path/to/nowhere is the full directory name.

Thanks jim mcnamara.

I am a bit confused. I was supposed to run this script on a unix host. Such as this way:

./(file name)

And inside the code, I am supposed to have path to directories where script is supposed to perform above checks..

Can you clarify what you meant?

Thanks

If you are working with a static directory then just replace this:

opendir (DIRHNDL, "$ARGV[0]") 

with your directory path:

opendir (DIRHNDL, "/my/dir/path") 

And call the script without any argument.

Hi jim mcnamara:

I tired to run the script and came up with syntax errors. I researched and fixed some but still I get these:

-bash-3.2$ ./file_check.pl
./file_check.pl: line 3: sub: command not found
./file_check.pl: line 5: =: command not found
./file_check.pl: line 6: -=: command not found
./file_check.pl: line 7: =: command not found
./file_check.pl: line 9: syntax error near unexpected token `('
./file_check.pl: line 9: `      $mtime = (stat("$_[0]"))[9] || die "cannot stat file $!";  '

Put the correct path of the perl interpreter in the shebang.
And pass the full directory path as a parameter.

tyler_durden

I did like this in the code now:

#!/usr/local/bin/perl -w
sub checkFile{

      $today = time;
      $today -= $today % 86400;
      $return_value = 0;
                                    #
      $mtime = (stat("$_[0]"))[9] || die "cannot stat file $!";
      $size =  (stat("$_[0]"))[7];  # size in bytes
      $ok = "not ok";

      if( $size > 0 && $mtime >= $today )
      {
            $ok = "ok";
            $return_value = 1;
      }
      print "$_[0] is $ok\n";
      return $return_value;
}

$found = 0;
opendir (DIRHNDL, "/loc1/partition4/server88") ||  die "Cannot open directory $!";
@filelist = readdir (DIRHNDL);
closedir (DIRHNDL);

foreach $filename ( @filelist )
{
   if ($filename =~ /txt$/)
   {
     $found |= checkfile $filename;
   }
}
print "return status = $found\n";

exit 0;

And I still get this:

-bash-3.2$ ./file_check.pl
./file_check.pl: line 3: sub: command not found
./file_check.pl: line 5: =: command not found
./file_check.pl: line 6: -=: command not found
./file_check.pl: line 7: =: command not found
./file_check.pl: line 9: syntax error near unexpected token `('
./file_check.pl: line 9: `      $mtime = (stat("$_[0]"))[9] || die "cannot  file $!";  '

What would be my mistake?

What's the output of -

type perl
which perl

tyler_durden

when i do type perl, i get this:

perl is hashed (/usr/local/bin/perl)

when i do which perl, i get this:

/usr/local/bin/perl

Check if the file is in dos format. If so, set it to Unix format in vim and save.

tyler_durden

I think tyler d is right - your file is probably munged. Did you use a windows editor to create your file? If you did, then look into dos2ux (or sometimes called dos2unix), this converts windows carriage control to unix carriage control. So the unix perl interpreter can run it without hysteria. The only other likelihood is that you have somehow installed a small subset of a standard perl installation.

I ran the code on a Solaris box with perl 5.9 -- it does run. The code is not really ready for production use, it is just an example. It needs parameter checking and other error trapping to be reasonable.

I would continue to recommend, that if this is a job-related project - use shell instead.

Hi guys, i did the dos2unix, and that helped. However I get different types of errors now:

-bash-3.2$ dos2unix file_check.pl

dos2unix: converting file file_check.pl to UNIX format ...

-bash-3.2$ ./file_check.pl

./file_check.pl: line 3: sub: command not found

./file_check.pl: line 5: =: command not found

./file_check.pl: line 6: -=: command not found

./file_check.pl: line 7: =: command not found

./file_check.pl: line 9: syntax error near unexpected token `('

./file_check.pl: line 9: `      $mtime = (stat("$_[0]"))[9] || die "cannot stat file $!";  '

What's the output of the following command ?

cat -veT file_check.pl

tyler_durden

Hi.. this is what i get:

-bash-3.2$ cat -veT file_check.pl

$

#!/usr/local/bin/perl$

sub ExampleFiles{$

$

      $today = time;$

      $today -= $today % 86400;  $

      $return_value = 0;$

                                    #  $

      $mtime = (stat("$_[0]"))[9] || die "cannot stat file $!";  $

      $size =  (stat("$_[0]"))[7];  # size in bytes$

      $ok = "not ok";$

      $

      if( $size > 0 && $mtime >= $today )$

      {$

            $ok = "ok"; $

            $return_value = 1;           $

      }$

      print "$_[0] is $ok\n";$

      return $return_value;$

}$

$

$found = 0;$

opendir (DIRHNDL, "/loc1/dir3") ||  die "Cannot open directory $!";$

@filelist = readdir (DIRHNDL);$

closedir (DIRHNDL);$

$

foreach $filename ( @filelist )$

{$

   if ($filename =~ /txt$/)$

   {$

     $found |= ExampleFiles $filename;$

   }$

}$

print "return status = $found\n";$

$

exit 0;$

$

$

$

-bash-3.

That looks ok.
What's the output of the following ?

perl -v
perl -V

tyler_durden

this is what i get:



-bash-3.2$ perl -v



This is perl, v5.8.7 built for i686-linux



Copyright 1987-2005, Larry Wall



Perl may be copied only under the terms of either the Artistic License or the

GNU General Public License, which may be found in the Perl 5 source kit.



Complete documentation for Perl, including FAQ lists, should be found on

this system using `man perl' or `perldoc perl'.  If you have access to the

Internet, point your browser at http://www.perl.org/, the Perl Home Page.



-bash-3.2$ perl -V

Summary of my perl5 (revision 5 version 8 subversion 7) configuration:

  Platform:

    osname=linux, osvers=2.6.9-78.0.13.el, archname=i686-linux

    uname='linux dopes.secrea.com 2.6.9-78.0.13.el #1 wed jan 7 17:31:05 est 2009 i686 i686 i386 gnulinux '

    config_args='-ds -e -Dprefix=/usr/local -Dinstallprefix=/usr/local/encap/perl-5.8.7'

    hint=recommended, useposix=true, d_sigaction=define

    usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef

    useperlio=define d_sfio=undef uselargefiles=define usesocks=undef

    use64bitint=undef use64bitall=undef uselongdouble=undef

    usemymalloc=n, bincompat5005=undef

  Compiler:

    cc='cc', ccflags ='-fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',

    optimize='-O2',

    cppflags='-fno-strict-aliasing -pipe -I/usr/local/include'

    ccversion='', gccversion='3.4.6 20060404 (Red Hat 3.4.6-10)', gccosandvers=''

    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234

    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12

    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8

    alignbytes=4, prototype=define

  Linker and Libraries:

    ld='cc', ldflags =' -L/usr/local/lib'

    libpth=/usr/local/lib /lib /usr/lib

    libs=-lnsl -ldb -ldl -lm -lcrypt -lutil -lc

    perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc

    libc=/lib/libc-2.3.4.so, so=so, useshrplib=false, libperl=libperl.a

    gnulibc_version='2.3.4'

  Dynamic Linking:

    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'

    cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib'





Characteristics of this binary (from libperl):

  Compile-time options: USE_LARGE_FILES

  Built under linux

  Compiled at May 27 2009 12:11:46

  @INC:

    /usr/local/lib/perl5/5.8.7/i686-linux

    /usr/local/lib/perl5/5.8.7

    /usr/local/lib/perl5/site_perl/5.8.7/i686-linux

    /usr/local/lib/perl5/site_perl/5.8.7

    /usr/local/lib/perl5/site_perl

    .

-bash-3.2$