Delete Select Email Messages from Mbox – Best Script Method

emailmuttscripting

I have an arbitrary email messages file in mbox format. I would like to periodically (end of the week), and automatically (via cron) purge messages from my "alerts" mbox file (new folder) just from one sender (or with a specific subject), because one sender let's call it 'syscheck@example.com' sends dozens of messages per day.

I want to cron this so daily it will do what I manually type in with mutt -f alerts; D; syscheck@example.com; $; y (purge)

.procmailrc is not an option because I have to actually skim over them all first. Once I have skimmed they are fine. At the end of the week they are no longer needed, and want them removed.

Best Answer

This cron job does what you specified daily at midnight:

0 0 * * * script >/dev/null -c 'env TERM=vt100 mutt -F/dev/null -falerts -e "push <delete-pattern>syscheck@example.com<enter><sync-mailbox>y<enter><exit>"' /dev/null

Let's break that down.

script -c 'cmd' runs cmd under a fake pseudo-tty (pty) so that cmd thinks it has a terminal with cursor mobility and such. Mutt needs this, but your cron job can't have it. Script provides the shim. Script's usual job is to record a command session to a file. Its final argument, /dev/null, says to write the record to the null device since you probably don't care about a bunch of replayable curses events.

env TERM=vt100 ... means to put a vt100 terminal in the environment before running mutt. You need this because cron jobs don't have a natural terminal type (since they don't naturally have a terminal).

Everything else is part of mutt. We use -F/dev/null to ensure that your .muttrc is not read. There's nothing wrong with reading it, but changes in your muttrc could change the way mutt interaction goes. It's safer over the long term to use the default muttrc only, which is what -F/dev/null does.

The -e option tells mutt what to do when it runs. The arguments to -e are commands that you can put into a muttrc file: set, alternatives, bind, hdr_order, etc. Push is a command that "pushes" keystrokes into the keyboard buffer, so that mutt interprets what follows as if you had typed it.

Now let's look at the virtual keystrokes.

<delete-pattern>syscheck@example.com<enter> is equivalent to keystrokes Dsyscheck@example.com plus ENTER, but it uses keyboard binding symbols instead of actual keystrokes. This is best practice for macros and for pushes, because it insulates your script against changes in default or personal keybindings. You can get key binding symbols from the interactive help. All the names in the middle column (that you use with the bind statement) are symbol names.

<sync-mailbox> is equivalent to pressing $, again with the key symbol instead of the keystroke. y<enter> responds to the "Are you sure?" prompt.

Finally, <exit> quits mutt. That also terminates your script session, and your cron command ends. The >/dev/null, per usual with cron, prevents any of the noise from cron from harassing your mailbox.

Note that the whole push string is quoted! That's important. Fortunately we only need two layers of quoting, so we can use double quotes inside singles without any ludicrous quote escaping.

Related Question