问题
I want to clean my mailbox from mails from specific address
I have thousands of messages, I want to do this in bash script, and run it from time to time (a receive SPAM from different addresses, and unfortunately my "spam filters" have only small effect on them)
回答1:
To interract with a mail server through command line, you could use either telnet
or openssl
.
You can connect to your pop server using the following command (I've taken gmail as an example. You'll have to look for your email host pop3 address and socket.) :
openssl s_client -connect pop.gmail.com:995 -quiet
As this command is interractive, it will ask for a username, a password and a serie of commands.
expect
is a tool that can automate interaction with interactive commands. The basic syntax is as follow : expect "somestring" action
-> If the program we monitor displays "somestring", we execute the action.
Here is a script that would delete all the messages present on your email address :
#!/usr/bin/expect
#you can modify the timeout if the scrpit fails
set timeout 1
#our connection variables
set ip "pop.gmail.com"
set socket "995"
set user "user.name"
set pass "password"
#we set the address we want to remove mails from here. Escape special regex characters such as dots.
set target_address "mail\.example@gmail\.com"
#we launch the subprocess we want to interact with
spawn openssl s_client -connect $ip:$socket -quiet
#if connection went all right, we try to login
expect -re ".OK.*" {send "user $user\r"}
expect -re ".OK.*" {send "pass $pass\r"}
#if login went alright, we try to count the messages on the server
#you will get the following output :
#+OK NB_MSG TOTAL_SIZE
expect -re ".OK.*" {send "stat\r"}
#if the stat command went allright ...
expect -re ".OK.*" {
#we extract the number of mail from the output of the stat command
set mail_count [lindex [split [lindex [split $expect_out(buffer) \n] 1] " "] 1]
#we iterate through every email...
for {set i 1} {$i <= $mail_count} {incr i 1} {
#we retrieve the header of the email
send "top $i 0\r"
#if the header contains "To: $target_address" (or "To: <$target_address>" or "To: Contact Name <$target_address>" ...)
#to filter according to the sender, change the regex to "\nFrom: ..."
expect -re "\nTo: \[^\n\]*$target_address" {
#we delete the email
send "dele $i\r"
}
}
}
expect default
You might need to alter your email account settings to allow the use of external programs
回答2:
Here I have written a similar script in PHP, by use of the IMAP function of PHP. I did not have Linux, so I could not use the bash script. However. I thought that sharing the PHP-script would provide a solution for those running WINDOWS and having access
<?php
echo "My showmail.php script";
// This is the format for opening the email connection:
//
// domain prt foldr[.<.subfolder........>] my@blp.com xxxxxxxx
// $connection = imap_open('{imap.one.com:143}Inbox.<write subfolder here>','email-name','password');
// Execution: (write this in the browsers address bar)
http://digitalageinstitute.com/showmail.php?fromdate=01%20January%202009&todate=28%20August%202018&search=@weheartit.com&email=david.svarrer@digitalageinstitute.com&password=xxxxxxx&domain=imap.one.com&folder=Inbox
//
// This line above, entered into a browsers address bar will execute this script (named showmail.php),
// from the servers root (www.digitalageinstitute.com), and
//
// will delete emails from the mail folder "Inbox" (case sensitive) for the user david.svarrer@digitalageinstitute.com, by use of
// the IMAP domain (this is where you access emails from outside) imap.one.com and at port 143 (see this, further down)
//
$emailaddress = $_GET["email"];
$emailpassword= $_GET["password"];
$fromdate = $_GET["fromdate"];
$todate = $_GET["todate"];
$search = $_GET["search"];
$domain = $_GET["domain"];
$folder = $_GET["folder"];
echo $emailaddress." ".$emailpassword." ".$fromdate." ".$todate." ".$search." ".$domain." ".$folder;
$connection = imap_open('{'.$domain.':143}'.$folder,$emailaddress,$emailpassword);
$ccount = imap_num_msg($connection);
$maxtoexpunge=20000;
echo "Parameters = ".$fromdate.",".$todate.",".$search.":".'ALL FROM "'.$search.'" SINCE "'.$fromdate.'" BEFORE "'.$todate.'"';
// $some = imap_search($connection, 'ALL FROM "Twitter"');
$some = imap_search($connection, 'ALL FROM "'.$search.'" SINCE "'.$fromdate.'" BEFORE "'.$todate.'"');
print_r ($some);
echo "<br/>Elements: ".count($some)."<br/>";
$expunge = 0;
for($msgno = 0; $msgno < count($some) ; $msgno++) {
// echo "Fetching element ".$some[$msgno]."<br/>";
$headers = imap_headerinfo($connection, $some[$msgno]);
//$position = True;
$position = strpos(" ".strtolower($headers->fromaddress), strtolower($search));
$position2 = strpos(" ".strtolower($headers->subject), strtolower($search));
if ($position || $position2) {
if ($expunge<$maxtoexpunge) {
imap_delete ($connection, $some[$msgno]);
echo "<br/>Deleting:".$expunge." sequence [".$msgno."]=".$some[$msgno]." ".$headers->fromaddress.", subject:".$headers->subject;
$expunge++;
} else {
echo "<br/>Skipping:"." sequence [".$msgno."]=".$some[$msgno]." ".$headers->fromaddress.", subject:".$headers->subject;
}
}
}
// The expunge command deletes after all action has been taken. DON'T call it until very end, as it will otherwise mess up message numbers!!
imap_expunge ($connection);
echo "<br/>Expunged!!<br/>";
/* Here are the keywords to be used for the imap search order.
toaddress - full to: line, up to 1024 characters
to - an array of objects from the To: line, with the following properties: personal, adl, mailbox, and host
fromaddress - full from: line, up to 1024 characters
from - an array of objects from the From: line, with the following properties: personal, adl, mailbox, and host
ccaddress - full cc: line, up to 1024 characters
cc - an array of objects from the Cc: line, with the following properties: personal, adl, mailbox, and host
bccaddress - full bcc: line, up to 1024 characters
bcc - an array of objects from the Bcc: line, with the following properties: personal, adl, mailbox, and host
reply_toaddress - full Reply-To: line, up to 1024 characters
reply_to - an array of objects from the Reply-To: line, with the following properties: personal, adl, mailbox, and host
senderaddress - full sender: line, up to 1024 characters
sender - an array of objects from the Sender: line, with the following properties: personal, adl, mailbox, and host
return_pathaddress - full Return-Path: line, up to 1024 characters
return_path - an array of objects from the Return-Path: line, with the following properties: personal, adl, mailbox, and host
remail -
date - The message date as found in its headers
Date - Same as date
subject - The message subject
Subject - Same as subject
in_reply_to -
message_id -
newsgroups -
followup_to -
references -
Recent - R if recent and seen, N if recent and not seen, ' ' if not recent.
Unseen - U if not seen AND not recent, ' ' if seen OR not seen and recent
Flagged - F if flagged, ' ' if not flagged
Answered - A if answered, ' ' if unanswered
Deleted - D if deleted, ' ' if not deleted
Draft - X if draft, ' ' if not draft
Msgno - The message number
MailDate -
Size - The message size
udate - mail message date in Unix time
fetchfrom - from line formatted to fit fromlength characters
fetchsubject - subject line formatted to fit subjectlength characters
*/
?>
来源:https://stackoverflow.com/questions/40374737/bash-script-delete-mails-from-specific-address-pop3-account