Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Deleting 10 day old backup folders if a current full backup exists

Status
Not open for further replies.

TheGuru10

Technical User
Sep 23, 2009
8
CA
Hello,
I have a perl script which deletes the folders by date but my goal is to check if a folder and file was created by capturing dates from folders and files and then execute the delete. If the folder and files do not exist then do nothing.

The below script only delete folders by date:

## Script to delete file older than * days

#!/usr/bin/perl
use POSIX qw(strftime);
use Win32;
use File::stat;
use Win32::OLE;

$Win32::OLE::Warn = 3;
$logdir="E:\\Scripts\\Logs";
$logfile=$logdir . "\\" ."clean.log";
$errfile=$logdir . "\\" ."clean.err";

close STDOUT;

open(STDOUT, '>>', $logfile);
close STDERR;
open(STDERR, '>>', $errfile);
print "\n\n................................\n";

my $now = localtime time;
print "$now\n";;

$Day = 10 ;
$hour = $Day * 24 ;



$Directory1 = "E:\\Scripts\\Backup\\database1" ;

printf ("Delete Folders under>> $Directory1 older than $hour hours\n\n");

opendir (DIR, "$Directory1/");
@DIR = readdir(DIR);
closedir (DIR);

chdir $Directory1;
## printf ("Directory1: $Directory1\n");

foreach $SubDir(@DIR) {
## printf ("SubDir: $SubDir\n");

if($SubDir =~ /.\b/)
{
$name1 = "$Directory1\\$SubDir";
## printf ("Name: $name1\n");

if (-M $name1 > $Day )
{
print "Deleting folder: $name1\n";
$objFSO = Win32::OLE->new('Scripting.FileSystemObject');
$objFSO->DeleteFolder($name1);

}
}

}


$Directory2 = "E:\\Scripts\\Backup\\database2" ;

printf ("\n\nDelete Folders under>> $Directory2 older than $hour hours\n\n");

opendir (DIR, "$Directory2/");
@DIR = readdir(DIR);
closedir (DIR);

chdir $Directory2;
## printf ("Directory2: $Directory2\n");

foreach $SubDir(@DIR) {
## printf ("SubDir: $SubDir\n");

if($SubDir =~ /.\b/)
{
$name1 = "$Directory2\\$SubDir";
## printf ("Name: $name1\n");

if (-M $name1 > $Day )
{
print "Deleting folder: $name1\n";
$objFSO = Win32::OLE->new('Scripting.FileSystemObject');
$objFSO->DeleteFolder($name1);

}
}

}

close STDOUT;
close STDERR;

 
TheGuru10 said:
I have a perl script which deletes the folders by date but my goal is to check if a folder and file was created by capturing dates from folders and files and then execute the delete. If the folder and files do not exist then do nothing.

I can't make sense of this... the script will only process folders that exist in the destination directory. Can you explain your requirements again please?

Regarding the current script, one improvement I would immediately make is to avoid repeating the entire block of code and instead place it inside a loop such as:

Code:
[olive][b]foreach[/b][/olive] [blue]$database[/blue] [red]([/red][red]qw/[/red][purple]database1 database2[/purple][red]/[/red][red])[/red] [red]{[/red]
    [blue]$Directory[/blue]=[red]"[/red][purple]E:[purple][b]\\[/b][/purple]Scripts[purple][b]\\[/b][/purple]Backup[purple][b]\\[/b][/purple][blue]$database[/blue][/purple][red]"[/red][red];[/red]
    [gray][i]# ...[/i][/gray]
[red]}[/red]

Annihilannic.
 
Also, I've never used Win32::OLE, but I'd guess you only need to create the new $objFSO once at the beginning of your script rather than every time a folder is removed.

Annihilannic.
 
Thanks,
I have modified the script as per your loop recomendation.

The requirement is that when a full backup is on Saturday then the database will generate a folder date "20090919" and under this folder that's where database will backupthe backup image file "220004.001".

The perl script attached only deletes any backup folders older then 10 days. My target is to check for the backup folder and file within the folder for current timestamp and then delete the folders older then 10 days. If the backup folder and image file is not created then do nothing and exit script. The delete script will run on Saturday that's when the backup image folder and file will be generated.

I hope this explains :)
Thanks.
 
So, in other words, you don't want to remove the old backups if the new backup didn't work?

Annihilannic.
 
Yes, you are correct. If the backup folder did not exist for the date when then script will run, it should not remove the old backups.
 
Something like this:

Perl:
[url=http://perldoc.perl.org/functions/use.html][black][b]use[/b][/black][/url] [green]POSIX[/green][red];[/red]

[gray][i]# ...[/i][/gray]

[maroon]DATABASE[/maroon][maroon]:[/maroon]	
[olive][b]foreach[/b][/olive] [blue]$database[/blue] [red]([/red][red]qw/[/red][purple]database1 database2[/purple][red]/[/red][red])[/red] [red]{[/red]
    [blue]$Directory[/blue]=[red]"[/red][purple]E:[purple][b]\\[/b][/purple]Scripts[purple][b]\\[/b][/purple]Backup[purple][b]\\[/b][/purple][blue]$database[/blue][/purple][red]"[/red][red];[/red]
    [url=http://perldoc.perl.org/functions/my.html][black][b]my[/b][/black][/url] [blue]$today_backup[/blue]=[blue]$Directory[/blue] . strftime [red]"[/red][purple]%Y%m%d[/purple][red]"[/red],[url=http://perldoc.perl.org/functions/localtime.html][black][b]localtime[/b][/black][/url][red];[/red]
    [olive][b]if[/b][/olive] [red]([/red] ! [url=http://perldoc.perl.org/functions/-X.html][black][b]-d[/b][/black][/url] [blue]$today_backup[/blue] [red])[/red] [red]{[/red]
        [url=http://perldoc.perl.org/functions/print.html][black][b]print[/b][/black][/url] [red]"[/red][purple][blue]$today_backup[/blue] does not exist, skipping cleanup for [blue]$database[/blue][purple][b]\n[/b][/purple][/purple][red]"[/red][red];[/red]
        [olive][b]next[/b][/olive] DATABASE[red];[/red]
    [red]}[/red]

    [gray][i]# ...[/i][/gray]

[red]}[/red]

Annihilannic.
 
Thanks,
The script works like charm. While testing the script, I was wondering if there is a way to perform file check for today date as well within the if statement. Because all the dated folders contains the backup image file for the same date. If not then we can keep as is because it is working great and just wanted to have extra precaution that's all.


DATABASE:

foreach $database (qw/DBTest1.0\DBTest1\NODE0000\CATN0000\ DBTest2.0\DBTest2\NODE0000\CATN0000\ /)
{
$Directory = "E:\\Scripts\\Backup\\$database";

my $today_backup=$Directory . strftime "%Y%m%d",localtime;
if ( ! -d $today_backup ) {
print "$today_backup does not exist, skipping cleanup for $database\n";
next DATABASE;
}

printf ("Delete Folders under>> $Directory older than $hour hours\n\n");

opendir (DIR, "$Directory/");
@DIR = readdir(DIR);
closedir (DIR);

chdir $Directory;
## printf ("Directory: $Directory\n");

foreach $SubDir(@DIR) {
## printf ("SubDir: $SubDir\n");


if($SubDir =~ /.\b/)
{
$name1 = "$Directory\\$SubDir";
##printf ("Name: $name1\n");


if(-M $name1 > $Day )
{
print "Deleting folder: $name1\n\n\n";
$objFSO = Win32::OLE->new('Scripting.FileSystemObject');
$objFSO->DeleteFolder($name1);

}
}

}


}
 
TheGuru10 said:
... to perform file check for today date ...

What do you mean by this? Check whether the file contains today's date? Whether it is in the file's name? Or whether the file was modified today?

Annihilannic.
 
To check wheather the file contains today's date under the folder. The same check we have it for the folder.
 
Well, you already know how to get today's date to get the file's name, so I guess all you need to add is a -f test for the file's existence. See perldoc -f -f.

Annihilannic.
 
Hi Annihilannic

I was trying to make a few modifications to the script.
We had it to delete backups older then X number of days under $Directory = "E:\\Scripts\\Backup\\$database";

There were archived logs generated by the database and I wanted to perform the similar delete operation as we did with the backups. The only problem is that the archived files are located under a different folder.
Is there a way to input a different path to delete the archived files after the backup date check has been completed.
Let me know if you need any further clarification.
Thanks.
 
Well... what exactly is the folder structure where the archived logs are stored? Can you not just use similar code using a different variable like $Directory? Perhaps rename the $Directory variable to $BackupDirectory and create a new one $ArchiveDirectory for the sake of clarity.

Annihilannic.
 
Thanks,

The archived files are located in a different folder structure other then the backup folder location.

I have modified the script but the issue will be for the second DBTest2 Archived database folder structure "E:\\Scripts\\ArchivedLogs\\DBTest2\\DBTest2\\NODE0000\\C0000009".

DATABASE:

foreach $database (qw/DBTest1.0\DBTest1\NODE0000\CATN0000\DBTest2.0\DBTest2\NODE0000\CATN0000\ /)
{
$BackupDirectory = "E:\\Scripts\\Backup\\$database";

my $today_backup=$BackupDirectory . strftime "%Y%m%d",localtime;
if ( ! -d $today_backup ) {
print "$today_backup does not exist, skipping cleanup for $database\n";
next DATABASE;
}


printf ("Delete Folders under>> $BackupDirectory older than $hour hours\n\n");

opendir (DIR, "$BackupDirectory/");
@DIR = readdir(DIR);
closedir (DIR);

chdir $Directory;
## printf ("Directory: $BackupDirectory\n");

foreach $SubDir(@DIR) {
## printf ("SubDir: $SubDir\n");


if($SubDir =~ /.\b/)
{
$name1 = "$BackupDirectory\\$SubDir";
##printf ("Name: $name1\n");


if(-M $name1 > $Day )
{
print "Deleting folder: $name1\n\n\n";
$objFSO = Win32::OLE->new('Scripting.FileSystemObject');
$objFSO->DeleteFolder($name1);

}
}

}



$ArchiveDirectory = "E:\\Scripts\\ArchivedLogs\\DBTest1\\DBTest1\\NODE0000\\C0000009" ;

printf ("Delete files under>> $ArchiveDirectory older than $hour hours\n\n");

opendir (DIR, "$ArchiveDirectory/");
@DIR = readdir(DIR);
closedir (DIR);

chdir $ArchiveDirectory;

foreach $file(@DIR) {


$name = "$ArchiveDirectory\\$file";

if (-M $name > $Day )
{
printf ("Deleting File: $file\n");
##unlink("$name");
}



}
 
Please post your code between [ignore]
Code:
 ...
[/ignore] tags to make it easier to read.

Aren't you missing a space?

Code:
foreach $database (qw/DBTest1.0\DBTest1\NODE0000\CATN0000\DBTest2.0\DBTest2\NODE0000\CATN0000\ /)
[COLOR=red]                                                          ^
												   here --+[/color]

Do you not also need to escape the backslashes, or does it work okay like that?

I think it would be best to set up a hash containing the directory info, e.g.

Code:
[blue]$BackupDirectories[/blue][red]{[/red][purple]db1[/purple][red]}[/red] = [red]"[/red][purple]E:[purple][b]\\[/b][/purple]Scripts[purple][b]\\[/b][/purple]Backup[purple][b]\\[/b][/purple]DBTest1.0[purple][b]\\[/b][/purple]DBTest1[purple][b]\\[/b][/purple]NODE0000[purple][b]\\[/b][/purple]CATN0000[/purple][red]"[/red] [red];[/red] 
[blue]$ArchiveDirectories[/blue][red]{[/red][purple]db1[/purple][red]}[/red] = [red]"[/red][purple]E:[purple][b]\\[/b][/purple]Scripts[purple][b]\\[/b][/purple]ArchivedLogs[purple][b]\\[/b][/purple]DBTest1[purple][b]\\[/b][/purple]DBTest1[purple][b]\\[/b][/purple]NODE0000[purple][b]\\[/b][/purple]C0000009[/purple][red]"[/red] [red];[/red] 

[blue]$BackupDirectories[/blue][red]{[/red][purple]db2[/purple][red]}[/red] = [red]"[/red][purple]E:[purple][b]\\[/b][/purple]Scripts[purple][b]\\[/b][/purple]Backup[purple][b]\\[/b][/purple]DBTest1.0[purple][b]\D[/b][/purple]BTest1[purple][b]\N[/b][/purple]ODE0000[purple][b]\C[/b][/purple]ATN0000[/purple][red]"[/red] [red];[/red] 
[blue]$ArchiveDirectories[/blue][red]{[/red][purple]db2[/purple][red]}[/red] = [red]"[/red][purple]E:[purple][b]\\[/b][/purple]Scripts[purple][b]\\[/b][/purple]ArchivedLogs[purple][b]\\[/b][/purple]DBTest1[purple][b]\\[/b][/purple]DBTest1[purple][b]\\[/b][/purple]NODE0000[purple][b]\\[/b][/purple]C0000009[/purple][red]"[/red] [red];[/red] 

[gray][i]#...[/i][/gray]

[maroon]DATABASE[/maroon][maroon]:[/maroon]
[olive][b]foreach[/b][/olive] [blue]$database[/blue] [red]([/red][url=http://perldoc.perl.org/functions/sort.html][black][b]sort[/b][/black][/url] [url=http://perldoc.perl.org/functions/keys.html][black][b]keys[/b][/black][/url] [blue]%BackupDirectories[/blue][red])[/red] [red]{[/red]
    [blue]$BackupDirectory[/blue] = [blue]$BackupDirectories[/blue][red]{[/red][blue]$database[/blue][red]}[/red][red];[/red]

    [gray][i]# ...[/i][/gray]

    [blue]$ArchiveDirectory[/blue] = [blue]$ArchiveDirectories[/blue][red]{[/red][blue]$database[/blue][red]}[/red][red];[/red]

    [gray][i]# ...[/i][/gray]
[red]}[/red]

Annihilannic.
 
Thank you and appreciate your help. The script works like a charm.

Code:
$BackupDirectories{db1} = "E:\\Scripts\\Backup\\DBTest1.0\\DBTest1\\NODE0000\\CATN0000\\" ; 
$ArchiveDirectories{db1} = "E:\\Scripts\\ArchivedLogs\\DBTest1\\DBTest1\\NODE0000\\C0000009\\" ; 

$BackupDirectories{db2} = "E:\\Scripts\\Backup\\DBTest2.0\\DBTest2\\NODE0000\\CATN0000\\" ; 
$ArchiveDirectories{db2} = "E:\\Scripts\\ArchivedLogs\\DBTest2\\DBTest2\\NODE0000\\C0000011\\" ; 


DATABASE:
foreach $database (sort keys %BackupDirectories) 
{
    $BackupDirectory = $BackupDirectories{$database};

   	my $today_backup=$BackupDirectory . strftime "%Y%m%d",localtime;
    	if ( ! -d $today_backup ) {
        print "\n\n!!!$today_backup does not exist, skipping cleanup for $database\n";
        next DATABASE;
    	}



	printf ("Delete Backup Folders under>> $BackupDirectory older than $hour hours\n\n");
 
	opendir (DIR, "$BackupDirectory/"); 
	@DIR = readdir(DIR);
	closedir (DIR);
	
	chdir $Directory;
	## printf ("Directory: $BackupDirectory\n");
	
	foreach $SubDir(@DIR) {
	## printf ("SubDir: $SubDir\n");

		
				if($SubDir =~ /.\b/)  
					{
					$name1 = "$BackupDirectory\\$SubDir";  
			   		##printf ("Name: $name1\n");

											      
					if(-M $name1 > $Day ) 
						{
						print "Deleting folder: $SubDir\n\n";
						##$objFSO = Win32::OLE->new('Scripting.FileSystemObject');
						##$objFSO->DeleteFolder($name1);
							
						}
					}
	
				}


    $ArchiveDirectory = $ArchiveDirectories{$database};



	printf ("Delete Archived Files under>> $ArchiveDirectory older than $hour hours\n\n");
 
	opendir (DIR, "$ArchiveDirectory/"); 
	@DIR = readdir(DIR);
	closedir (DIR);

	chdir $ArchiveDirectory;

	foreach $file(@DIR) {

  	
		$name = "$ArchiveDirectory\\$file";  
		      
			if (-M $name > $Day ) 
			{
				printf ("Deleting File: $file\n");
                		##unlink("$name");
			}		


		}

}
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top