Decode MIME Mailboxes Safely with decodemail
You will finish with a readable output mailbox whose message parts have been decoded, plus a repeatable way to recode text as UTF-8 without accidentally 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. The command reads and transforms mail; it does not send messages. 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. It is a useful troubleshooting boundary because the command line is then visible in the command itself. Once the result is understood, you can remove that option if your Mailutils configuration is part of the intended workflow.
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
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 concerns. 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
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
The option --truncate, or -t, truncates the output mailbox if it exists. This is destructive: 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
Keep the backup until you have checked the replacement. If the conversion is wrong, restore it with:
$ 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.
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. Keep configuration and privileges controlled
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.
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
If the output is 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. If MIME text remains encoded, inspect the message's content type and transfer encoding, then try the explicit --recode --charset=UTF-8 form. 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
- The installed version is known and the input and output mailboxes are separate.
- A conversion completed with exit status 0 and the output was checked.
- UTF-8 conversion uses
--recode --charset=UTF-8when that is the requirement. --truncateis used only after a backup or an explicit decision to replace the output.- Repeated runs use a fresh destination or deliberately account for duplicates.
- Normal conversions run without elevated privileges where file permissions allow.