#!/usr/bin/perl ################################################## # mop -- Überflüssige Backup-Dateien löschen # Mike Schilli, 2001 (m@perlmeister.com) ################################################## use 5.6.0; use warnings; use strict; use File::Basename; use Getopt::Std; use Date::Calc qw(Today Add_Delta_Days Add_Delta_YMD Day_of_Week); my $BAK_DIR = "/data/backups"; # Kommandozeilenoptionen einsammeln my %OPTS; eval { local $SIG{__WARN__} = sub {}; getopts('nv', \%OPTS); } or usage("Bad option"); my %files = (); my %dates_needed = (); # Gewünschte Backup-Tage errechnen calc_dates(\%dates_needed); # Backup-Dateien analysieren for my $file (<$BAK_DIR/*>) { # mtime als Hash-Value speichern $files{$file} = (stat $file)[9]; } # Nach letztem Modifikationszeitpunkt # sortiert durchlaufen for my $file (sort { $files{$a} <=> $files{$b} } keys %files) { my $mtime = $files{$file}; my ($md, $m, $y) = (localtime($mtime))[3..5]; my $date = sprintf "%d %d %d", $y + 1900, $m+1, $md; if(exists $dates_needed{$date} or $date eq join ' ', Today()) { print "Keeping $file\n" if $OPTS{v}; # Datum entfernen -- nur erste Datei # eines Tages wird aufgehoben delete $dates_needed{$date}; } else { if($OPTS{n}) { print basename($file), " can go away.\n"; } else { unlink $file or die "Cannot unlink $file ($!)"; print basename($file), " deleted.\n" if $OPTS{v}; } } } ################################################## sub calc_dates { ################################################## my ($needed) = @_; # Erwünschte Backup-Tage errechnen my @today = Today(); # Tage letzter Woche for my $delta (1..7) { my @date = Add_Delta_Days(@today, -$delta); $needed->{"@date"} = 1; } # Die letzten 4 Montage my $current_dow = Day_of_Week(@today); my @last_monday; if($current_dow == 1) { # Heute ist Montag @last_monday = Add_Delta_Days(@today, -7); } else { # Heute ist nicht Montag @last_monday = Add_Delta_Days(@today, 1-$current_dow); } for my $weeks_back (0..3) { my @date = Add_Delta_Days(@last_monday, $weeks_back * -7); $needed->{"@date"} = 1; } # Die letzten 3 Monatsersten my @last_first; if($today[2] == 1) { # Heute ist der Monatserste @last_first = Add_Delta_YMD(@today, 0, -1, 0); } else { # Heute ist nicht der Monatserste @last_first = ($today[0], $today[1], 1); } for my $months_back (0..2) { my @date = Add_Delta_YMD(@last_first, 0, -1 * $months_back, 0); $needed->{"@date"} = 1; } } ################################################## sub usage { ################################################## my ($message) = @_; my $program = basename($0); print <