Decode MIME Mailboxes to UTF-8 with decodemail
A mailbox full of base64 and quoted-printable is no use to grep, and decodemail turns it into readable text in one command. This guide ends with a decoded output mailbox and a repeatable way to recode text as UTF-8 without destroying an existing result. The examples use GNU Mailutils decodemail 3.17, installed here from package version 1:3.17-1.1build3.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about ten minutes.
- You need: a readable input mailbox, a writable destination, and the Mailutils package.
- It will not: send anything. The command reads and transforms mail only.
- Safest start: work on a copy first if the mailbox contains anything you may need to preserve.
1. Check the installed command
Confirm which program will run and record its version:
$ command -v decodemail
/usr/bin/decodemail
$ decodemail --version
decodemail (GNU Mailutils) 3.17
The exact copyright and licence lines may vary, but the version should identify the installed Mailutils release. The local manpage describes the positional arguments as INBOX and OUTBOX. They are source and destination mailboxes, not email addresses.
Checkpoint
If command -v finds nothing, stop here and install Mailutils through your normal package-management process. Do not replace the binary with a downloaded script.
2. Decode a mailbox into a new file
Choose a destination that does not already contain useful mail, then pass the input and output paths:
$ decodemail --no-config /path/to/inbox.mbox /path/to/decoded.mbox
$ printf 'exit status: %s\n' "$?"
exit status: 0
--no-config keeps site and user configuration files out of this first test, so the command line is the whole story. Once the result is understood, you can drop that option if your Mailutils configuration is part of the intended workflow.
What it does: GNU describes decodemail as a mailbox conversion tool. Text parts of multipart messages are decoded to plain text, while non-multipart messages and parts that cannot be decoded are transferred verbatim. Message headers and mailbox bookkeeping can therefore differ from the input even when the message content is unchanged.
Verify that the destination exists and is non-empty without opening it in a mail client:
$ test -s /path/to/decoded.mbox && echo 'output mailbox is non-empty'
output mailbox is non-empty
$ grep -c '^Subject:' /path/to/decoded.mbox
1
Tip
The subject count is only a quick check. A message may have no Subject: header, and a mailbox can use a format that is not plain mbox text. Treat the command's exit status and a format-aware reader as the stronger verification.
3. Recode text parts as UTF-8
Decoding a transfer encoding and changing a character set are separate jobs. For a predictable UTF-8 result, request the output charset and enable recoding:
$ decodemail --no-config --recode --charset=UTF-8 \
/path/to/inbox.mbox /path/to/decoded-utf8.mbox
$ printf 'exit status: %s\n' "$?"
exit status: 0
--recode, also written-R, recodes text parts to the current charset.--charset=UTF-8, also written-c UTF-8, selects the output charset.
Supplying both makes the intention clear in a script and leaves decoded text parts labelled as UTF-8.
Inspect the headers and a small amount of text:
$ sed -n '1,35p' /path/to/decoded-utf8.mbox
$ file -b /path/to/decoded-utf8.mbox
ASCII text
Tip
file may report another result when the mailbox contains non-ASCII characters or mixed content. Do not treat that one line as proof that every message part has the same encoding. Check representative messages, especially those that originally used legacy charsets.
4. Decide what happens to an existing output
Warning
The option --truncate, or -t, truncates the output mailbox if it exists. Any messages already in that destination are removed before the new conversion is written. Use it only when replacing the destination is deliberate.
$ cp --preserve=all /path/to/decoded.mbox /path/to/decoded.mbox.bak
$ decodemail --no-config --truncate \
/path/to/inbox.mbox /path/to/decoded.mbox
$ printf 'exit status: %s\n' "$?"
exit status: 0
Recovery
Keep the backup until you have checked the replacement. If the conversion is wrong, restore it with the command below.
$ mv /path/to/decoded.mbox.bak /path/to/decoded.mbox
When the destination should accumulate another run, use --no-truncate. The installed command appends converted messages to an existing mailbox in that mode. Appending can create duplicates if you process the same input twice, so use a fresh destination for repeatable jobs or track which input has already been handled.
Warning
Do not use shell redirection to create the output, such as decodemail input > output. The program's second positional argument is the outbox it opens and updates. Redirection captures standard output instead and does not express the mailbox operation you intend.
5. Control configuration and privileges
Mailutils tools can read site and user configuration. Use --no-config for an isolated conversion, or choose an explicit file with --config-file=/path/to/mailutils.conf. That option implies --no-config. Before relying on a configuration file, ask the program to lint it:
$ decodemail --no-config --config-file=/path/to/mailutils.conf --config-lint
$ printf 'exit status: %s\n' "$?"
exit status: 0
This checks syntax and exits; it does not convert a mailbox. If you only want to see the available configuration settings, use --config-help or --show-config-options. Do not put passwords into a command copied into shell history or a shared script.
Security warning
Run the conversion as an ordinary user when the mailbox files are readable and the destination is writable. Use elevated privileges only to access a protected mailbox directory, and prefer fixing ownership or permissions through the system's normal mail administration. Running the whole conversion as root can leave the output owned by root and harder for the mailbox owner to use.
6. Diagnose the likely failures
If the command cannot open the input, check the path and permissions without changing anything:
$ ls -l /path/to/inbox.mbox
$ test -r /path/to/inbox.mbox && echo readable
$ test -w /path/to && echo destination-directory-writable
- Output empty or unchanged. Confirm that you supplied the intended input and that the destination is not the same file. Keep the input and output paths distinct while testing.
- MIME text still encoded. Inspect the message's content type and transfer encoding, then try the explicit
--recode --charset=UTF-8form. - Some parts untouched. Parts that Mailutils cannot decode are intentionally copied verbatim rather than guessed at.
For option details or a short syntax reminder, run:
$ decodemail --help
$ decodemail --usage
These options include debugging and configuration controls, but they do not turn decodemail into a mail sender or a message editor. Keep destructive output replacement, credentials, and service changes outside a blind batch command.
Done means
- Version known. The installed version is recorded and the input and output mailboxes are separate.
- Clean run. A conversion completed with exit status 0 and you checked the output.
- UTF-8 on purpose. Conversion uses
--recode --charset=UTF-8when that is the requirement. - Truncate with care.
--truncateis used only after a backup or an explicit decision to replace the output. - No surprise duplicates. Repeated runs use a fresh destination or deliberately account for duplicates.
- No needless root. Normal conversions run without elevated privileges where file permissions allow.