Operating System - HP-UX
1820882 Members
3615 Online
109628 Solutions
New Discussion юеВ

Perl Code help to clean 7 days old log files

 
SOLVED
Go to solution
Becke
Super Advisor

Perl Code help to clean 7 days old log files

Hi Guys,

I'm fairly new to perl, I'm writing a simple perl script to clean up the log files older than 7 days, my script below works fine upto where its copying the files to log directory.

However when I'm unable to figure out on how to delete the files older than 7 days in my code below.

Please let me know how to delete files older than 7 days in the code below, what else I need to do in the code?? and also if I'm wrong in the code anywhere?...here is the code

#!/usr/bin/perl
foreach (glob("*")) {
print;
my $age = -M ;
my $logfile = "/var/spool/cleanlogs.out";
if ($age > 7) {
OPEN (STDOUT, ">>$logfile");
print " IS OVER 7 days old\n";
} else {
print " is ",int($age)," days old\n";
CLOSE (STDOUT);
}
}
##############################################

Output starts ...

4gen is 0 days old
am is 3 days old
badday.jpg is 5 days old
courseend.linux IS OVER 7 days old
courseend.ms IS OVER 7 days old
cw IS OVER 7 days old
d06 is 1 days old
dl IS OVER 7 days old

Cheers,
Raf
33 REPLIES 33
James R. Ferguson
Acclaimed Contributor
Solution

Re: Perl Code help to clean 7 days old log files

Hi Raf:

$_ contains the name of the current list element from the 'foreach' loop, as you are aware.

Thus:

...
print "$_ is over 7-days old...deleting\n";
unlink $_;

unlink() will work on a list or $_ if omitted.

Regards!

...JRF...
Hein van den Heuvel
Honored Contributor

Re: Perl Code help to clean 7 days old log files


As JRF indicates, you can use unlink to delete.

>> I'm fairly new to perl,....

Free advice...

1) The script is a litlle scary, in that it will merrily delete anything from anywhere if 'accidently' run. Maybe change the wildcard to "*.log" as appropriate, or include a partial directory ( "log/*" ). Somethign, anything to stop it from unqualified deletes.
Or... replace the unlink by a 'rename $_, $to_be_deleted'. Using this $to_be_deleted directory as staging for a final delete.

2) Don't use the same literal twice. Ever. Declare a variable/constant and use that.
my $MAX_AGE = 7;
:
if ($age > $MAX_AGE) {
:
print "IS OVER $MAX_AGE days old\n";


3) Don't overload STDOUT/STDERR/STDIN
Whoever reads you script later will be mighty confused to find STDOUT is NOT really that.
Use something simple, yet more descriptive, for example LOG or OUT or CLEAN.

Cheers!
Hein.
Becke
Super Advisor

Re: Perl Code help to clean 7 days old log files


Thank you very much James and Hein my scripts works like a charm,

James I have followd your instructions and included $_, but I agree with Hein that it is a bit scary to run,

I have couple of more questions

1. What do I do in my code so, it recreates the log file every time I run the script??

2. Hein to stop it from unqualified deletes, can you please correct my code below, as i only want to delete log files in '/var/spool/uv/test' directory, and also i don't want to append the log file, i just wanna recreate it everytime the script runs...

Please correct my code below...

#!/usr/local/bin/perl
use strict;
foreach (glob ("*u*")) {
print;
my $logfile = "/var/spool/uv/test/cleanfiles.out";
my $result = -M;
if ($result > 7) {
open (STDOUT, ">>$logfile");
print "$_ is over 7 days old..removing\n";
unlink $_;
} else {
print " is ",int($result), " days old\n";
close (STDOUT);
}
}
Arunvijai_4
Honored Contributor

Re: Perl Code help to clean 7 days old log files

Hi Raf,

When do you want to create log file, during the time of execution or after that ?

-Arun
"A ship in the harbor is safe, but that is not what ships are built for"
Hein van den Heuvel
Honored Contributor

Re: Perl Code help to clean 7 days old log files

To change append to re-create, just replace >> with >

>> only want to delete log files in '/var/spool/uv/test' directory,

Maybe simple hard-code that part.
Better still, combine it with the cleanuplog.

I guess there is no conflict with the log file, as that will be recent.

>> Please correct my code below...

Here is a quick, untested, attempt:


#!/usr/local/bin/perl
use strict;
my MAX_AGE = 7;
my TEST_DIR = "/var/spool/uv/test/";
my $logfile = $TEST_DIR . "cleanfiles.out";

open (LOG, ">$logfile") or die "failed to create new $logfile";

foreach (glob ("${TEST_DIR}*")) {
my $result = -M;
if ($result > $MAX_AGE) {
print LOG "$_ is over $MAX_AGE days old..removing\n";
unlink $_;
} else {
$result = int($result);
print LOG "$_ is $result days old\n";
}
}
close LOG;
Hein van den Heuvel
Honored Contributor

Re: Perl Code help to clean 7 days old log files


Here is an other thought, in case you are really worried about accidental deletes.

Make that log file dual - function.

Make the recent file comment lines,
and turn the "over 7" lines into remove commands.
Now after running the first script, review the log, and then actually execute the log.

Again untested...

:
open (LOG, ">$logfile") or die "failed to create new $logfile";
print LOG "#!/usr/bin/sh";

foreach (glob ("${TEST_DIR}*")) {
my $result = -M;
if ($result > $MAX_AGE) {
print LOG "rm $_ \n";
} else {
$result = int($result);
print LOG "# $_ is $result days old\n";
}
:

Becke
Super Advisor

Re: Perl Code help to clean 7 days old log files


Hi Hein,

Thanks for your help mate, it really helped me get my script working..

sorry if i confused you, all I need to know, how do only delete something in '/var/spool/uv/test' directory with files starting with 'u'....

your latest post didn't help me but the very first one did...

Please let me know...

P:S Arun I need to delete the log files after I genereated the log of what its going to remove....

Cheers,
Raf
Muthukumar_5
Honored Contributor

Re: Perl Code help to clean 7 days old log files

Raf,

You can go with shell built-in utility like find as,

find /var/spool/uv/test -name "u*" -mtime +7 -exec rm -i {} \;

It will ask your input to delete. If you don't want then remove that -i option.

--
Muthu
Easy to suggest when don't know about the problem!
Muthukumar_5
Honored Contributor

Re: Perl Code help to clean 7 days old log files

More better,

find /var/spool/uv/test -name "u*" -type f -mtime +7 -print | xargs rm -f

--
Muthu

Easy to suggest when don't know about the problem!
Arunvijai_4
Honored Contributor

Re: Perl Code help to clean 7 days old log files

Hi Raf,

Using "find" and deleting will be another way of doing it.

-Arun
"A ship in the harbor is safe, but that is not what ships are built for"
Arunvijai_4
Honored Contributor

Re: Perl Code help to clean 7 days old log files

A very good link,

http://dunedin.lug.net.nz/forums/showthread.php?t=40730

-Arun
"A ship in the harbor is safe, but that is not what ships are built for"
Yogeeraj_1
Honored Contributor

Re: Perl Code help to clean 7 days old log files

Hi Raf,

for an alternative solution, please see also:
http://forums1.itrc.hp.com/service/forums/questionanswer.do?threadId=1001861

hope this helps too!

kind regards
yogeeraj
No person was ever honoured for what he received. Honour has been the reward for what he gave (clavin coolidge)
Hein van den Heuvel
Honored Contributor

Re: Perl Code help to clean 7 days old log files


>> your latest post didn't help me but the very first one did...

It did. You are just not quite ready to recognize it.
Check back after a few days/weeks more of playing with perl

:-)
:-)

Hein.

James R. Ferguson
Acclaimed Contributor

Re: Perl Code help to clean 7 days old log files

Hi (again) Raf:

Hein has provided you some excellent guidelines to follow now and as you progress. I agree with hime when he says to check back after a bit more "playing".

Let me add one more piece of advice at this point.

If you are writing anything more than (perhaps) a one-line command line script, begin with:

use strict;
use warnings;

If you are writing one-line command line scripts, at least add the '-w' switch (the less robust version of the 'warnings' pragma.

You will save yourself countless hours of debugging, unnecessary repetitions of testing and possibly protect yourself from very costly mistakes!

Regards!

...JRF...
Becke
Super Advisor

Re: Perl Code help to clean 7 days old log files


Hi Hein and James,

I really appreciate your help guys, after playing with the script bit more, I was able to get it working O.K...

Its great to see that we have a great team here and everyone is quite happy to share their knowledge with others...By the do u guys know any good perl forum that I can join??????

PS: Arun I'm trying to learn perl, so I don't want to write shell script commands to perform this task....Thanks everyone for always responding.....I will now assign more points

Cheers,
Raf
James R. Ferguson
Acclaimed Contributor

Re: Perl Code help to clean 7 days old log files

Hi (again) Raf:

I'm happy that we were able to help you.

You will find these sites very informative:

http://www.perlmonks.org/

http://www.cpan.org/

http://www.perl.com/

http://www.perl.org/

Enjoy the journey!

Regards!

...JRF...
Becke
Super Advisor

Re: Perl Code help to clean 7 days old log files


Hi James,

Thanks for the further info..I might be bothering you guys in the near future to get some occasional help in perl...I'm extremely keen to become a competent perl programmer:)...

Many Regards,
Raf

Arunvijai_4
Honored Contributor

Re: Perl Code help to clean 7 days old log files

Hi Raf,

Some more interesting Perl sites,

http://learn.perl.org/library/beginning_perl/
http://unix.org.ua/orelly/perl/index.htm

-Arun
"A ship in the harbor is safe, but that is not what ships are built for"
Becke
Super Advisor

Re: Perl Code help to clean 7 days old log files


Hi Hein and James,

I need your help again, although I have got the script working but i really need to change my code, as I don't want to use -M (match operator) and glob funtion in my code.

Could you guys please correct my code below so I can use 'OPENDIR' function, instead of using 'glob' and also I want to use the "Time::Local" module...

I still need to delete files older than seven days...Please help as its urgent...
Below is my code again, please correct it.

#!/usr/bin/perl
foreach (glob("*")) { #instead of this I wanna use OPENDIR funtion here#
print;
my $age = -M ; #I don't want to use -M operator to match..Please correct it#
my $logfile = "/var/spool/cleanlogs.out";
if ($age > 7) { #This statement will be changed once u correct it#

OPEN (STDOUT, ">>$logfile"); #I dont want to use 'STDOUT' to send the output to a file,so this has to be changed, please correct this as well'#.

print " IS OVER 7 days old\n";
} else {
print " is ",int($age)," days old\n";
CLOSE (STDOUT);
}
}
Yogeeraj_1
Honored Contributor

Re: Perl Code help to clean 7 days old log files

hi Raf,

COncerning the "time::local". below a simple example that can help you:

use Time::Local;
$time = timelocal($sec,$min,$hours,$mday,$mon,$year);
$time = timegm($sec,$min,$hours,$mday,$mon,$year);

$time = timelocal(50, 45, 3, 18, 0, 73);
print "Scalar localtime gives: ", scalar(localtime($time)), "\n";
$time += 28 * 365.2425 * 24 * 60 * 60;
print "Twenty-eight years of seconds later, it's now\n\t",
scalar(localtime($time)), "\n";


for more information, please see:
http://www.unix.org.ua/orelly/perl/prog3/ch32_44.htm

hope this helps!

kind regards

yogeeraj
No person was ever honoured for what he received. Honour has been the reward for what he gave (clavin coolidge)
Yogeeraj_1
Honored Contributor

Re: Perl Code help to clean 7 days old log files

hi again,

sorry for not giving you the right solution to your script. But still, i believe these examples would be more beneficial to you and you can make necessary amendments easily.

For the Manipulating Files and Directories, you can refer to the following examples:
=============================================
Manipulating Directories :: Directory Access
=============================================
* If you want to change directories you can issue the chdir command:

chdir("/some/path") || die "Cannot chdir to /some/path ($!)";

* In order to glob a list, you can do it in either of these two ways:

@a =
@a = glob("/some/path/*.c");

This would create a list of all of the .c files in the /some/path directory. We could loop through a glob directly by:

if (-d "/some/path") {
$where = "/some/path";
} else {
$where = "/another/path";
}
while (defined($next = <$where/*.c>)) {
print "found a c file in $where directory named $name\n";
}

Notice the use of the -d check for a directory for its existence. Very powerful indeed.


=============================================
Manipulating Directories :: Directory Handles
=============================================
* Just like we can create file handles for our files, we can create directory handles for our directories!

* Using Directory Handles:

opendir(DIRHANDLE, "/some/path") || die "Cannot opendir /some/path: $!";
foreach $name (sort readdir(DIRHANDLE)) {
print "found file: $name\n";
}
closedir(DIRHANDLE);

This prints out a sorted directory listing. For an unsorted list, we could have simplified the loop construct:

while ($name = readdir(DIRHANDLE)) {
print "found file: $name\n";
}

Remember to close your directory handles!


more information available at:
http://vergil.chemistry.gatech.edu/resources/programming/perl-tutorial/filedir.html

hope this helps too!

kind regards
yogeeraj
No person was ever honoured for what he received. Honour has been the reward for what he gave (clavin coolidge)
Becke
Super Advisor

Re: Perl Code help to clean 7 days old log files


Thanks Yogeeraj,

Thank you for your detailed info mate, however I'm trying to work out myself how to get this sorted, but lets see if James or Hein can just correct my code as this is really important to get this right using this new method.

Cheers,
Raf
Hein van den Heuvel
Honored Contributor

Re: Perl Code help to clean 7 days old log files

>> don't want to use -M (match operator)

Why not? It is a fine unary file operator, NOT a match operator. If we don;t understand what is deemed to be wrong with -M, then how can anyone come up with the 'right' solution. Note: There is no 'file create time' on Unix, not matter waht call or tool you use.

>> and glob funtion in my code.

Ditto. Why replace it? What's wrong with it?
OPENDIR is much more work.

Could you guys please correct my code below so I can use 'OPENDIR' function, instead of using 'glob' and also I want to use the "Time::Local" module...

>> OPEN (STDOUT, ">>$logfile"); #I dont want to use 'STDOUT' to send the output to a file,so this has to be changed, please correct this as well'#.

This was corrected in the earlier examples using 'LOG'. What was wrong with that?
The major change there really was to move the open/close outside the main processing loop

Good luck!
Hein.
Becke
Super Advisor

Re: Perl Code help to clean 7 days old log files


Hi Hein,

I totaly agree with you as there is no harm using -M operator, I have worked hard to do some research and understood how to use -M operator and globbing, but unfortunately my senior colleague is being smart and idiot and he wants me to write this script using OPENDIR function and use local:time function...

With your help I have sorted out everything but I think my senior has got problems, he thinks -M operator and using 'glob' function is just not right, "what a joker" no one at work likes him to be honest:)

Could you please do me a favour and correct the code when you get a chance so I can get this resolved..

Thanks for your support and help...

Many Regards,
Raf