8

I'm sure I once had a way to read email files from the commandline that was fall-off-a-log simple but I can't for the life of me find it again now.

I have files in MailDir format, I wish to view their contents (headers, body (HTML/plain), MIME-decoded, extract attachments maybe). These aren't my emails; it's not that I want a MUA capable of fetching, sorting, sending mail for me - they're just raw files that I need to inspect.

artfulrobot
  • 2,929
  • cat would work – Chris Davies May 13 '21 at 12:29
  • 1
    cat can't decode mime or base64. mutt -f /path/to/Maildir would work better. But you're probably thinking of the ancient MH aka Message Handling System, or new MH aka nmh. Command-line tools for manipulating mailboxes. I'm not sure if the original MH could handle Maildir (probably not, Maildir is shiny & new compared to MH) but New MH can. BTW, this is packaged as nmh on debian. Probably most other distros too. – cas May 13 '21 at 13:22
  • @cas thanks, mutt works great as a UI for browsing a maildir, thanks. nmh looks plain scary: mhshow looked promising but won't do anything without me first setting up a mail account, talks about scanning and moving stuff: exactly what I don't want. @roaima: cat also can't handle flowed content. – artfulrobot May 13 '21 at 13:55
  • 1
    Yeah, i first encountered MH about 30 years ago. Ran screaming to elm. After a brief dalliance with pine, I now use mutt. I'll post my comment as an answer. – cas May 13 '21 at 14:00
  • elm now there's a blast from the past. I misread the question and thought the last line meant that no decoding was necessary. Ooips. – Chris Davies May 13 '21 at 18:19

3 Answers3

10

The package maildir-utils (at least it's called so in Debian) contains a program called mu, that has a nice functionality to display the contents of a Maildir mail message. It displays only the headers, the text/plain part plus list of attachments. See man page.

Example: mu view /path/to/email-file.

If you have an email with text/html MIME, mu can extract it to a separate file: mu extract /path/to/email-file --parts=1 (which outputs to 1.msgpart by default, assuming the HTML is the first part.)

raj
  • 1,123
  • 4
  • 11
7

Use mutt -f /path/to/Maildir. Or mutt -R -f /path/to/Maildir if you want mutt to open the mailbox in read-only mode.

The command-line tools you're thinking of are probably MH aka Message Handling System, which is ancient and un-maintained, or New MH which is still actively maintained.

I don't think the ancient mh can handle Maildir/ mailboxes, but nmh definitely can.

nmh is packaged as nmh on Debian, and probably on most other distros too.

cas
  • 78,579
2

reformime is a command (from the maildrop package on Debian/Ubuntu) which can be used to extract the body of an email file.

You can get a list of MIME parts with reformime -i <your-message which gives you something like

section: 1
content-type: multipart/alternative
content-transfer-encoding: 8bit
charset: UTF-8
content-language: en-GB
starting-pos: 0
starting-pos-body: 2494
ending-pos: 75170
line-count: 1287
body-line-count: 1241

section: 1.1 content-type: text/plain content-transfer-encoding: 8bit charset: utf-8 starting-pos: 2578 starting-pos-body: 2666 ending-pos: 8180 line-count: 181 body-line-count: 178

section: 1.2 content-type: multipart/related content-transfer-encoding: 8bit charset: UTF-8 starting-pos: 8220 starting-pos-body: 8303 ending-pos: 75128 line-count: 1054 body-line-count: 1051

section: 1.2.1 content-type: text/html content-transfer-encoding: 8bit charset: utf-8 starting-pos: 8343 starting-pos-body: 8415 ending-pos: 25276 line-count: 343 body-line-count: 340

And then you can extract a section with reformime -e -s 1.1 e.g. this would extract the plain text version (1.1). Likewise, if section 1.2.3 is an image you could view it like reformime -e -s 1.2.3 <mail.eml | display :-

So if you just want to see the plain text version you can 'easily' do it with a handy one-liner:

F=/path/to/the-email-file
reformime -e -s $(reformime -i <$F | fgrep -B1 'content-type: text/plain' | head -n1 | cut -c 10- ) <$F

This is not quite the easy option I'd hoped to find, but thought I'd document it anyway!

artfulrobot
  • 2,929