Скрипт для массового удаления писем из очереди postfix
Приведенный ниже скрипт удаляет письма из очереди, старше указанного времени в секундах, отправленные с определенного адреса или в определенный адрес
Uasge: ./clean_queue <find-email-option> <age of email in seconds> Find-email-option: -f=<form-addr> -t=<to-addr> Suggestions about age in seconds: 86400 sec = 1d; 43200 sec = 12h; 18000 sec = 5h; 3600 sec = 1h; 300 sec = 5m
В качестве <form-addr>
или <to-addr>
можно указывать регулярные выражения.
Примеры использования:
Удалить письма старше чем 1час, отправленные с ящика tester@example.com:
clean_queue -f=tester@example.com 3600
Удалить письма старше чем 1 час, отправленные в адрес tester@example.com
clean_queue -t=tester@example.com 3600
Внимание! Скрипт рассчитан только на локаль en-US!
Если у вас русская локаль, то перед запуском нужно выполнить 'export LANG=en_US; ', или исправить значения хэша %months
в процедуре date_to_timestamp
Скрипт clean_queue
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | #! /usr/bin/perl use strict; use warnings; use Time::Local; # $debug = 0: do the job # $debug = 1: do not delete anything, only print debug info my $debug=1; # Variables my $flag_to_from; my $addr; my $message_age; my $query; my @lines; my $grep_options; my $count=0; # Check used programs for existence my ($mailq, $grep, $date, $postsuper) = &search_for_binaries('mailq','grep','date','postsuper'); # Parse commandline &print_usage if scalar @ARGV != 2; ($flag_to_from,$addr,$message_age) = &parse_options (\@ARGV); # compute timestamp before which we must delete messages my $timestamp_to_delete = time-$message_age; # print info for user before we do the job print "\nTis script will delete mails from queue with following paramerets:\n"; print "$flag_to_from: $addr\nOlder than: ",scalar(localtime($timestamp_to_delete)),"\n"; print "\nPress enter to process or <control>+c to abort\n"; <stdin>; # set variables and get mailqueue entities if ($flag_to_from eq "From") { $query='^(\w+).*\s+\d*\s(.+)\s+'.$addr; $grep_options = '-A2 -E'} elsif ($flag_to_from eq "To") { $query='^\s+'.$addr; $grep_options = '-B2 -E' } else { die "Something going wrong.."; } @lines = `$mailq | $grep $grep_options \'$query\'`; foreach my $line (@lines){ chomp $line; # Find lines like (may be broken): # E56758823F 901099 Thu Oct 27 06:09:10 markswoman@cebol.us # EE31288357 4456 Thu Oct 27 09:27:38 MAILER-DAEMON if ( $line =~ /^(\w+)\s+\d+\s(.+)\s+([\S+\@\S+]+)/ ) { my $message_id = $1; my $time_in_log = $2; my $timestamp_in_log = &date_to_timestamp($time_in_log); if ( $timestamp_in_log < $timestamp_to_delete ) { $count ++; print "$line\n"; print "\tParsed as: $message_id\t $time_in_log\n" if $debug > 0; print "\tTimestamp in log: $timestamp_in_log\n" if $debug > 0; print "\tTimestamp before delete: $timestamp_to_delete\n" if $debug > 0; print "\tDifferences: ",$timestamp_in_log-$timestamp_to_delete,"\n" if $debug > 0; # In this line we do the real job!! system "$postsuper -d $message_id" if $debug < 1; } } } print "Deleted $count messages\n"; exit; # # ====== Subroutines ======== # sub parse_options { my @options = @{shift()}; my $flag_to_from; my $addr; my $message_age; # parse <find-email-option> if ( $options[0] =~ /-f\=(.+)/ ) {$flag_to_from = "From"; $addr = $1; } elsif ( $options[0] =~ /-t\=(.+)/ ) {$flag_to_from = "To"; $addr = $1; } else { &print_usage; } # parse <age of email in seconds> if ( $options[1] =~ /^(\d+)$/ ) { $message_age = $1; } else { &print_usage; } return $flag_to_from,$addr,$message_age; } sub print_usage { print "Usage: ./clean_queue <find-email-option> <age of email in seconds>\n"; print "Find-email-option:\n"; print "\t-f=<form-addr>\n"; print "\t-t=<to-addr>\n"; print "Suggestions about age in seconds:\n"; print "\t86400 sec = 1d; 43200 sec = 12h; 18000 sec = 5h; 3600 sec = 1h; 300 sec = 5m\n"; exit; } sub search_for_binaries { my @prog_path; my $prog_name; while ( $prog_name = shift() ){ push (@prog_path, `which $prog_name` || die "cant find mailq $prog_name"); } chomp (@prog_path); return @prog_path; } sub date_to_timestamp { # subroutine get date in format "Tue Oct 18 02:46:57 2016" and return epoch timestamp my $date_str=shift(); my %months=( 'Jan'=>'01','Feb'=>'02','Mar'=>'03','Apr'=>'04','May'=>'05','Jun'=>'06','Jul'=>'07','Aug'=>'08','Sep'=>'09','Oct'=>'10','Nov'=>'11','Dec'=>'12' ); my $year = `$date +%Y`; my @date_arr = split (' ', $date_str); my $mon = $date_arr[1]; $mon = $months{$mon}; my $mday = $date_arr[2]; my ($hour, $min, $sec) = split (':', $date_arr[3]); my $timestamp=timelocal($sec, $min, $hour, $mday, $mon-1, $year) || die "Can't parse date: $date_str correct format is: Tue Oct 18 02:46:57 2016"; return $timestamp; } |