5

In a script I am trying to finish writing now, I need to get the oldest unread message from the current user's mailbox (specifically, I need the subject line for this project).

After extracting the oldest message, I also need to forward it to a different user for archive purposes.

How can I extract just that information in bash or Python?

Would it be better to use to extract the subject line into a file and then forward the message, requiring only file processing by the script? If so, how could I do that instead?

6
  • Warren, please don't use the kbd tag for commands such as that. It isn't what they're used for. They're to denote actual keyboard shortcuts, procmail is an actual command which should only be wrapped like I had fixed it: procmail.
    – slm
    Apr 28, 2014 at 22:48
  • @sim - I gave seen them used that way across the SE family to link to tags
    – warren
    Apr 29, 2014 at 4:14
  • The tags at the bottom is all that is needed. No need to do it like that within the question. Notice there's a procmail tag that's already linking to the tag wiki topic on procmail.
    – slm
    Apr 29, 2014 at 4:30
  • 1
    Incidentally I believe they do it like this: procmail i.e. [tag:procmail]. For example: meta.stackexchange.com/questions/194690/remove-the-linked-tag
    – slm
    Apr 29, 2014 at 4:36
  • 1
    Your Q your call but it's a little out of place (at least on this SE site). I've never seen anyone do it before you and I'm the 2nd highest editor on this site, so I stand by my edit. The grammar change was correct that I made too, as is often the case there's more than one way to phrase things 8-)
    – slm
    Apr 29, 2014 at 15:22

3 Answers 3

2

In conventional mbox systems, the first message in /var/mail/you is -- by definition -- unread and the oldest available.

formail -zxSubject: -1 -s </var/mail/you

To extract the message to a file (so you can conveniently forward just that message) and then extract the Subject: header, try something like

tmp=$(maketemp -t findoldestunread.XXXXXXXX) || exit 127
trap 'rm -f $tmp' EXIT   # remove temp file when done
trap 'exit 1' 1 2 3 5 15 # remove also in case of error / interruption
formail -1 -s </var/mail/you >"$tmp"
formail -zxSubject: <"$tmp"
sendmail -oi uncannyvictim@example.com <"$tmp"

In Maildir, the situation is somewhat more complex. New messages are temporarily stored in tmp and then moved to cur. The file name indicates flags; in so many words, look for a file name containing a comma near the end where S is not among the characters after the comma.

find path/to/Maildir/cur -maxdepth 1 -type f \
    -regex '.*,[^S,]*$' -printf '%C@ %p\n' |
sort | sed '1s/^[^ ]* //;q' | xargs formail -zxSubject:

The printf format specifier prints the timestamp first for easy sorting. We sort, grab the first line, trim the timestamp, and feed it to formail for extracting the Subject: header. (This will obviously break if you have funky file names with newlines in them or something; there are ways around that, but I'm lazy and practical here.)

Refactoring to just print the file name should be trivial in this case -- just remove the pipe to xargs and capture the output into a variable.

Some Maildir implementations will also have an index of some sort which might make this task a lot easier and faster than traversing the entire mailbox in the file system, but again, without more knowledge about which implementation you are using, this is just a speculative note at this point.

If your mailbox is not in either of these two formats, (you are weird and) you will need to update your question with more details.

Your reference to mail implies that you are probably using a traditional Berkeley mbox system, but there are many versions, some of which are somewhat esoteric.

1

The mail command can be used non-interactively to print out the list of emails in the inbox:

mail -H | head -1
>U     1  jenny@mybox.example.com Tue Apr 29 14 08:13 18/774    "Subject of mail"
2
  • how does that help wrt moving that message out of the inbox? Also, is '1' guaranteed to be the oldest?
    – warren
    Apr 29, 2014 at 15:15
  • 1
    Sorry, I read to quickly - it doesn't help with forwarding. But at least it's guaranteed to be the oldest email.
    – Jenny D
    Apr 30, 2014 at 7:59
-1

There are at least three mail delivery formats. It would help to know which one you are using.

formail will read a mail file and can output headers from particular message via skip and total options. This assumes the messages have been deliver into a known file. If you want to archive all the messages this would be a suitable tool.

procmail is more suitable to archiving the messages as they arrive. It can easily be configured to send a copy to another address while delivering. There are standard methods to avoid mail locks, and skip certain types of messages.

5
  • How do I determine which type I have?
    – warren
    Apr 29, 2014 at 4:15
  • @warren Your mail server should be configured to deliver to a certain type. The mail command reads from the users inbox in /var/mail. Maildir delivery uses a directory tree, usually called Maildir and locate in the user's home directory. I haven't knowingly worked with the third format.
    – BillThor
    Apr 29, 2014 at 4:22
  • 1
    While informative, this would be better suited as a comment, as it does not actually answer the question.
    – tripleee
    Apr 29, 2014 at 6:44
  • I tried to fix "looks" which I assume was meant to be "locks" but I cannot make edits that minor.
    – tripleee
    Apr 29, 2014 at 6:45
  • @tripleee, fixed :)
    – Ramesh
    Apr 29, 2014 at 15:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.