0

SpamAssassin has a feature to "learn" spam. Each user has a .spam folder in their mail folder and they will be instructed to move any spam into that folder. (Users are using IMAP.) I have set up a cron job to feed the contents of each account's .spam folder into sa-learn.

02 02 * * * sa-learn -p ~/.spamassassin/user_prefs --spam ~/mail/*/*/.spam/{cur,new} 

This works as intended, according to the cron confirmation email.

I now wish to autodelete the contents of the .spam folders on successful completion of the sa-learn command. Am I correct in thinking I can add the following onto the end of the above cron task?

&& rm ~/mail/*/*/.spam/{cur,new}

Does this look correct?

Notes: this is being tested for use on multiple cPanel reseller hosting acounts. I do not have shell access.


Update 1 after Celada's answer and comments below:

The way you need to do this is to atomically move each message to a different directory which you control and which the IMAP server doesn't touch, then process and delete it from within that location. Fortunately you are using Maildir which permits such atomic moves.

How about

mkdir -p /tmp/sa_tmp 
  && mv ~/mail/*/*/.spam/{cur,new} /tmp/sa_tmp
  && sa-learn -p ~/.spamassassin/user_prefs --spam /tmp/sa_tmp
  && rm -rf /tmp/sa_tmp

I'm deliberately not using mktemp so that if a directory gets left behind it will be deleted on the next run.


Update 2 after xhienne's comment:

Not sure moving the directories cur and new is a good idea => move their content instead. Moreover, there will be a name collision since you are moving many directories named new and cur to the same destination.

I'm not sure how to avoid filename collisions.

Finally, moving to /tmp might mean moving to another partition, with the incurred extra-I/Os and the possibility of lacking disk space (/tmp is sometimes a small separate partition) => preferably, move to a special folder like ~/mail/.sa-learn that you can delete in the end

mkdir -p ~/mail/.sa-learn 
  && mv ~/mail/*/*/.spam/{cur,new}/* ~/mail/.sa-learn
  && sa-learn -p ~/.spamassassin/user_prefs --spam ~/mail/.sa-learn
  && rm -rf ~/mail/.sa-learn

Update 3:

I think this doesn't work if the new folder doesn't exist. I'm getting error:

mv: cannot stat `/home/username/mail/*/*/.spam/new/*': No such file or directory

There don't seem to be any "ignore" switches for mv. Any ideas?

1
  • Not sure moving the directories cur and new is a good idea => move their content instead. Moreover, there will be a name collision since you are moving many directories named new and cur to the same destination. Finally, moving to /tmp might mean moving to another partition, with the incurred extra-I/Os and the possibility of lacking disk space (/tmp is sometimes a small separate partition) => preferably, move to a special folder like ~/mail/.sa-learn that you can delete in the end.
    – xhienne
    Commented Jan 9, 2017 at 1:12

1 Answer 1

1

Your proposed solution is racy. Because you cannot guarantee that no new mail will be added (or, for that matter, deleted or changed) while sa-learn is running or in between running sa-learn and rm, many exciting and unfortunate things can happen, the most obvious of which is that you may delete mails without feeding them to sa-learn.

The way you need to do this is to atomically move each message to a different directory which you control and which the IMAP server doesn't touch, then process and delete it from within that location. Fortunately you are using Maildir which permits such atomic moves.

3
  • Good points. (1) I think if I run the cron in the middle of the night that's unlikely to happen. (2) If it does happen we just miss a little learning and no real harm is done. I'll go for simplicity and clarity rather than worry about race conditions. Is my syntax correct? (Respond in your answer and I can accept it.)
    – Transistor
    Commented Jan 8, 2017 at 21:14
  • You almost certainly want to remove the contents of the new and cur directories, not the directories themselves, so I'd change it. But... I can't recommend that you do that. It's easy enough to move them into a spool folder and probably even increases clarity too.
    – Celada
    Commented Jan 8, 2017 at 21:16
  • Please review the update to my question with solution along the lines you've suggested.
    – Transistor
    Commented Jan 8, 2017 at 22:58

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .