• Welcome to Computer Association of SIUE - Forums.
 

Calling all Perl Wizards

Started by R. Andrew Lamonica, 2004-10-06T10:36:50-05:00 (Wednesday)

Previous topic - Next topic

R. Andrew Lamonica

I need a perl script that does the following rather scary task and our â€Ã...“perl guyâ€Ã, is gone for a few weeks.

When run, the perl script searches a folder for all its sub-folders that were created (or modified) more than an hour ago and removes them and their contents.  This is scary because if the script by mistake matches the â€ËÅ".’ or â€ËÅ"..’ folders then a great deal of damage could be done.  For this reason, I am hesitant to just try some things.  

Requirements:
1. Script must be perl and must work with â€Ã...“perl-5.8.3-18â€Ã,.
2. Script should not take a great deal of time to run.
3. No output should be displayed or written to files other then the log (if you want).
4. If there are no sub-folders more then an hour old, then nothing should be done.
5. No assumptions should be made about the names of the sub-directories or their files, save that they will all be decedents of the specified parent directory.
6. Comments should be included in the script anywhere that the code is unclear.

Optional:
1. All operations should be enclosed in a function (â€Ã...“subâ€Ã,)

The writer of the script will be given credit on the â€Ã...“Web-based cross compilerâ€Ã, page located on http://roboti.cs.siue.edu . You can e-mail me (rlamoni on the school’s mail server) or just post the code.

William Grim

Andy, if 'find' had worked well in /bin/sh, I would have had a script for you that was 5 lines and did just as much!  Oh well....

Uncomment the "system(rm....);" line when you are ready to actually use the script with removal capabilities.

UNF!


#!/usr/bin/perl -w
#
# Per your requirements, this script does not output anything to the screen.
# Because this script does not print anything to the screen, it means you need
# to pass proper input to the script before running it.  Otherwise, it will
# fail, and you will have a difficult time determining the cause.
#
# This script removes directories from the specified parent directory (from the
# command line) if the modification time is more than an hour old.
#
# Arguments expected from command line:
#

use strict;
use Fcntl ':mode';
# Walks a directory tree, checking if sub-directories are >= 60 minutes old.
# If they are, it recursively removes the directory and continues scanning
# the current directory.
#
# This function is recursive.
sub walk_directory
{
        my ($parent_dir, $logfilename) = @_;
        open(FOUT, ">>$logfilename");

        opendir(PARENT, $parent_dir) or return -1;
        my @entries = readdir(PARENT);
        foreach my $file (@entries)
        {
                my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
                                $atime,$mtime,$ctime,$blksize,$blocks) =
                        stat("$parent_dir/$file");

                if (!S_ISDIR($mode) || $file eq '.' || $file eq '..')
                {
                        next;
                }

                if (time - $mtime >= 3600)
                {
                        print FOUT "$parent_dir/$file has modification time olde                                "than 60 minutes.\n";
#system("rm -rf $parent_dir/$file");
                }
                else
                {
                        walk_directory("$parent_dir/$file", $logfilename);
                }
        }
        closedir(PARENT);
        close(FOUT);
        return 0;
}

if (scalar(@ARGV) < 2)
{
        exit -1;
}

open(STDERR, '>/dev/null');
exit walk_directory @ARGV;
William Grim
IT Associate, Morgan Stanley

William Grim

Uhhh, xoops put backslashes in front of my quotes.  Go to http://snow.cs.siue.edu/~unix/rm_old.pl to get the code instead.
William Grim
IT Associate, Morgan Stanley

William Grim

Well, I misread the man page for find last night.  I had a small shell script written that does the job just as well as the perl script but with less lines of code.

Here is the code:

#!/bin/sh
#
# Runs 'find' to remove directories with modification times >= TIME minutes.

PATH=/usr/local/bin:/usr/bin:/bin

rm_old()
{
        PARENT=$1
        TIME=$2
        LOGFILE=$3

        find ${PARENT} -type d -mmin +${TIME} -exec rm -rf {} \; \
        >>${LOGFILE} 2>/dev/null
}

[ $# -lt 3 ] && exit -1

rm_old ${1} ${2} ${3}


Again, I bet XOOPS will fudge up my code; so, you can get it at http://snow.cs.siue.edu/~unix/rm_old.sh
William Grim
IT Associate, Morgan Stanley