Search a Mailbox Precisely with readmsg.mailutils
Grepping a raw mbox file risks a mangled multi-line match, readmsg.mailutils pulls out one message cleanly instead. It is also available as readmsg on systems that provide that alias, and it controls how much header information appears and makes repeated matches explicit.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about 10 minutes for a first pass. You need GNU Mailutils installed and read access to the mailbox you are inspecting. The examples use a placeholder mailbox path, replace it before running them. Reading a mailbox does not need elevated privileges unless its file permissions demand them, use the least privilege that can actually read the file.
1. Check the installed command
This guide was checked with GNU Mailutils 3.17, Debian package version 1:3.17-1.1build3. Confirm the version and see what your own host offers:
readmsg.mailutils --version
readmsg.mailutils --help
The installed manpage calls this a message printer. It has no option for deleting or moving messages and does not treat a mailbox as something to modify. Treat every run as a read operation, but still keep sensitive message contents out of terminals, logs and copied command output.
Checkpoint
The version command should identify GNU Mailutils. Missing executable? Install the distribution's Mailutils package rather than substituting an unrelated program with the same short name.
2. Select a mailbox and a message
Use --folder, or its short form -f, to select a mailbox explicitly:
readmsg.mailutils --folder=/path/to/mailbox 'Weekly report'
The selection text is positional. With the default --exact mode, Mailutils searches for an exact string and prints the first matching message. Quote the selection when it contains spaces or shell characters, that protects the text from the shell, it does not change Mailutils' matching rules.
A mailbox path is data, not a command. Do not paste an untrusted path into a shell expression that contains substitutions or redirections: keep it as the value of --folder and inspect it first.
Need every matching message, not just the first? Add --show-all-match, or -a:
readmsg.mailutils --folder=/path/to/mailbox --show-all-match 'Weekly report'
Without that option, a repeated subject or body match can look complete while it silently stops after the first message. Fine for a quick lookup, unsafe for an audit or export where completeness actually matters.
Checkpoint
Run the command once with a distinctive phrase. Wrong message? Make the selection more specific or move to pattern matching next. Nothing printed? Check the mailbox path, permissions and spelling.
3. Choose the matching mode deliberately
Exact matching is the default. The installed command also supports shell-style globbing and POSIX regular expressions:
# A shell-style pattern
readmsg.mailutils --folder=/path/to/mailbox --glob --show-all-match 'Weekly*'
# A POSIX regular expression
readmsg.mailutils --folder=/path/to/mailbox --regex --show-all-match 'Weekly (report|digest)'
Use --ignorecase when letter case should not matter:
readmsg.mailutils --folder=/path/to/mailbox --ignorecase 'weekly report'
Globbing and regular expressions are different languages. Do not write a regular expression and assume --glob will interpret it. If a pattern gets hard to review, test it against a copy of representative mail first and keep --show-all-match on so you can actually see the result.
4. Control headers and message content
By default, output includes the normal selected headers. --header or -h shows the entire header, including fields normally left out. --no-header or -n gives you a body-only result:
# Show every header field
readmsg.mailutils --folder=/path/to/mailbox --header 'Incident 4821'
# Omit all headers
readmsg.mailutils --folder=/path/to/mailbox --no-header 'Incident 4821'
These options change what is printed, not what is matched. A header field can still drive a selection even when it is hidden from the output, so confirm you want the body-only view before reaching for --no-header.
Use --mime to decode MIME messages on output:
readmsg.mailutils --folder=/path/to/mailbox --mime 'Invoice attached'
Warning
Decoded output can be much larger and far less recognisable than the stored message. Redirect it only somewhere with suitable permissions, and remember attachments or encoded content may contain secrets or active files. Do not execute anything just because this command printed it.
For multiple messages, --form-feeds places form-feed characters between them. That can help a pager or printer separate records, but it can confuse a line-oriented tool, so leave it off when another program expects ordinary text lines.
5. Make scripts predictable
For a script, name the mailbox, matching mode and header policy explicitly rather than relying on a user's configuration or the defaults:
readmsg.mailutils \
--no-config \
--folder=/var/mail/example \
--exact \
--show-all-match \
--no-header \
'Build finished'
--no-config stops site and user configuration files loading, which reduces surprises when the same script runs under different accounts. Need a particular configuration on purpose? Use --config-file=/path/to/mailutils.conf, which the manpage says also implies --no-config.
Do not add --debug to a normal output pipeline. It is diagnostic, and it can expose mailbox details or break machine-readable output. Run it separately when chasing a failure, and only where the message data is safe to see.
Check configuration syntax without printing any messages:
readmsg.mailutils --config-lint --config-file=/path/to/mailutils.conf
The lint command checks syntax and exits. It does not prove the mailbox exists, that the account can read it, or that a selection will actually match.
Common failure points
- No output: verify the exact mailbox path and test a distinctive phrase. Check permissions with
stat /path/to/mailbox, and reach for elevated privilege only if your mailbox policy actually requires it. - Only one result: the default prints just the first match. Add
--show-all-matchwhen completeness matters. - Unexpected case behaviour: exact matching is case-sensitive unless you add
--ignorecase. - Unreadable output: MIME decoding changes presentation. Compare the same selection without
--mimebefore deciding the stored message is damaged. - Output differs between hosts: configuration files vary. Add
--no-configand make the important options explicit.
Done means
- Version confirmed: you checked the installed GNU Mailutils version.
- Mailbox named explicitly: you set the intended mailbox with
--folder. - Matching mode chosen: exact, glob or regular-expression matching was a deliberate pick.
- Completeness checked: you used
--show-all-matchwhenever the first result was not enough. - Output kept safe: header and MIME output were deliberate choices, and sensitive output stayed out of unsafe logs.
- Scripts are explicit: any script you wrote used explicit options and, where appropriate,
--no-config.