This article was originally titled “The mail command on Linux” and published in 2014. The original body actually described sending mail through a local MTA, not receiving it. Its real recipient address, personal home directory, uuencode attachments, and unknown HTTP attribution are also unsuitable as current operational examples.
This edition reconstructs the title as a safe receiving guide. It first separates a local system mailbox, remote IMAP/POP3, and outgoing mail, then uses provider-authoritative settings, verified TLS, constrained credentials, and reversible one-way synchronization for the smallest useful test. Examples use the reserved .invalid domain and must be replaced with your provider’s official values; never execute placeholder configuration unchanged.
An inert archive of the historical body appears at the end. For privacy, only six personal recipient-address occurrences and two personal home-directory occurrences were replaced; the unchanged original remains in
source_exportand Git history. Commands in the archive must never be executed.
Table of Contents
Determine where “receiving” happens first
| Need | Data location | Suitable tool | Critical boundary |
|---|---|---|---|
| Read mail delivered to a local Unix account | Local system mailbox or mbox | The local mail/mailx implementation | It does not automatically connect to an Internet mailbox; exit semantics affect where read mail remains |
| Interactively read a remote mailbox while preserving server folders | IMAP server | A current MUA supporting TLS and the provider’s authentication, such as NeoMutt | IMAP state can change in both directions; constrain deletion and flag sync first |
| Synchronize a remote mailbox into a backup-friendly local Maildir | IMAP plus a local replica | Current mbsync/isync | Synchronization is not backup; state, deletion, and expunge need separate control |
| Download mail through a legacy workflow | POP3 server to local storage | Only when the provider formally supports it and the requirement truly matches | Client defaults vary and may delete server copies or lose folder semantics |
| Send mail | MTA or mail-submission service | SMTP submission client/MTA | SMTP is the outgoing path, not a retrieval protocol; it is not configured here |
Ask the provider or administrator first: whether IMAP is enabled, hostname, implicit-TLS port, authentication mechanism, username format, OAuth client policy, app-password conditions, quota, throttling, retention, server folder/label semantics, and whether third-party command-line clients are allowed. Do not copy endpoints from forum posts or reuse SMTP credentials as IMAP credentials.
Local mailx reads only a local mailbox
POSIX mailx has send and receive modes. Without recipient operands it enters receive mode and reads the current Unix user’s system mailbox by default; the concrete path, package, and implementation are system-defined. Begin with read-only discovery:
command -v mail
command -v mailx
If neither exists, use current supported distribution documentation to choose an implementation; do not install an ancient random RPM. If one exists, read its local manual and establish whether it operates on mbox, Maildir, or another backend. The following is a POSIX-style interactive entry point, not a remote IMAP login:
mailx
At the interactive prompt, first list headers, read one approved test message, and then use the no-change exit command:
headers
type 1
exit
Under POSIX semantics, exit leaves the mailbox unchanged; quit may move read system mail into mbox, commit deletions, or save state. Implementations can extend or alter behavior, so the local man mailx is authoritative. Do not use -u other-user to read another person’s mailbox; doing so requires extra privilege and may violate privacy and audit boundaries.
The terminal, scrollback, screen recording, and shell-session logs may display sender, subject, and body. Read only in a controlled terminal, and remove addresses, subjects, Message-IDs, tokens, and content before sharing diagnostics.
Prefer IMAP and modern TLS for remote mail
IMAP manages folders, messages, and flags on a server; POP3 is closer to download-style access; SMTP submission sends mail. The protocol names are not interchangeable. RFC 8314 recommends TLS for mail access and registers implicit-TLS ports 993 for IMAPS and 995 for POP3S. A provider may also support STARTTLS, but authentication must never continue after a downgrade to plaintext.
| Setting | Security requirement | Stop condition |
|---|---|---|
| Host and port | Use only current official provider/admin values; commonly IMAPS 993 | IP address, shortened link, mirror tutorial, or certificate name mismatch |
| TLS | Verify certificate chain, hostname, and validity under current system TLS policy | Any request to ignore certificates, “trust all,” or downgrade TLS |
| OAuth | Provider-approved client, minimal and revocable token scope, token stored in a keyring | Copying browser cookies, pasting a token on a command line, or granting unrelated access |
| App password | Only when officially supported, MFA is enabled, and OAuth is inapplicable | Main account password, shared password, or credential that cannot be revoked independently |
| Local account | Dedicated unprivileged user with minimally accessible directories | Routine reading as root or group/world-readable configuration and mail |
OAuth tokens remain secrets. RFC 7628 provides the advantage of limited access that can be revoked separately from a long-term account password; it does not permit exposing a token in configuration, process arguments, or logs. If OAuth is required, choose a current client with native OAUTHBEARER/XOAUTH2 support and follow the provider’s registration flow exactly. Never extract a token from a web session yourself.
Probe TLS without sending credentials
Before writing client configuration, make one TLS-handshake check against the provider-confirmed IMAPS endpoint. The .invalid host below is deliberately unusable; before replacing it, verify that the installed OpenSSL supports these options:
openssl s_client -connect imap.example.invalid:993 -servername imap.example.invalid -verify_hostname imap.example.invalid -verify_return_error -brief </dev/null
Passing means the certificate chain and hostname validate and the protocol satisfies system policy. The command does not authenticate to the mailbox or prove that credentials, permissions, or folders work. If validation fails, check system time, DNS, proxy, provider status, and CA packages. Do not add an ignore-verification option or permanently trust a server leaf certificate that was not independently verified.
Handshake output exposes the host, certificate subject, and network environment, so retain only necessary fields in a ticket. On a network with a managed enterprise proxy, obtain the managed trust solution from the administrator instead of temporarily disabling checks.
Use an isolated configuration for a pull-only IMAP experiment
The following uses mbsync to demonstrate boundaries; it is not a recommendation for a particular distribution package or mail provider. Confirm the installed version and official manual first. The test uses separate configuration, Maildir, and state directories, stops on any name collision, and never overwrites existing settings:
config="$HOME/.config/isyncrc-example"
mailroot="$HOME/Mail/example"
state="$HOME/.local/state/isync-example"
test ! -e "$config" && test ! -L "$config" || { echo "Stop: $config already exists"; exit 1; }
test ! -e "$mailroot" && test ! -L "$mailroot" || { echo "Stop: $mailroot already exists"; exit 1; }
test ! -e "$state" && test ! -L "$state" || { echo "Stop: $state already exists"; exit 1; }
umask 077
mkdir -p -- "$HOME/.config" "$HOME/.local/state"
install -d -m 700 -- "$mailroot" "$state"
install -m 600 /dev/null "$config"
Use a trusted local editor to place the following in the newly created empty file. Replace the host and username, but do not add Pass; let the client prompt for the provider-approved app password during an interactive run. If unattended operation is necessary, use an audited keyring helper with PassCmd and first prove that it does not write the secret into arguments, standard error, or logs.
IMAPAccount example
Host imap.example.invalid
Port 993
User user@example.invalid
TLSType IMAPS
SystemCertificates yes
IMAPStore example-remote
Account example
MaildirStore example-local
SubFolders Verbatim
Path ~/Mail/example/
Inbox ~/Mail/example/INBOX
Channel example-inbox
Far :example-remote:
Near :example-local:
Sync Pull New
Create Near
Remove None
Expunge None
SyncState ~/.local/state/isync-example/
This configuration selects only INBOX and pulls new messages from far to near. It does not push local changes, propagate deletion, or expunge. A real run still reads message content and leaves a sensitive copy on disk. If the mailbox uses OAuth, do not place an access token in Pass; stop this password example and switch to an OAuth flow jointly supported by the client and provider.
Simulate first, then perform one bounded synchronization
Disable shell tracing and session recording, and do not enable debug options that print protocol payloads or message bodies. Inspect file permissions and the configuration diff, then use the official --dry-run mode:
stat -c '%a %n' "$HOME/.config/isyncrc-example" "$HOME/Mail/example" "$HOME/.local/state/isync-example"
mbsync -c "$HOME/.config/isyncrc-example" --dry-run example-inbox
--dry-run connects, authenticates, and queries state without changing a mailbox or synchronization state. Its output may still contain folder or message metadata and must not be pasted publicly. Stop on any certificate, authentication, quota, permission, or folder-mapping anomaly. Do not retry repeatedly and trigger lockout or throttling.
After approval, execute exactly one named channel rather than using -a for every configured account:
mbsync -c "$HOME/.config/isyncrc-example" example-inbox
Accept by checking the local new-message count, sample hash/size, timestamps, attachments, and encoding, then confirming in the provider’s web interface that remote messages, flags, and folders did not change. Do not make production mail the first test; use a dedicated test account and non-sensitive seed messages. For a large first mailbox, have the provider administrator and client documentation establish a bounded strategy rather than guessing consistency by killing the process.
Keep local reading separate from synchronization
mbsync copies; an MUA such as NeoMutt reads. First point the MUA only at the new local Maildir, give it no remote account or sending configuration, and confirm that local deletion, moves, and read flags cannot return through the current one-way channel. Maildir-opening options and state behavior vary by client, so follow that version’s official manual instead of assuming that mailx reads Maildir.
Back up the local replica and sync state before reading. Even a header-only diagnostic can disclose sensitive information; do not open production mail in shared terminals, CI logs, or screenshots. Treat HTML mail, attachments, and external images as untrusted: do not execute scripts, automatically open attachments, or load remote tracking images, and inspect suspicious files with a separate security process.
“Synchronized” does not mean “backed up.” Sync can replicate state or future deletions; backup requires independent versions, retention, integrity verification, and a restore drill. This experiment deliberately disables deletion propagation until an owner defines the full policy.
Use POP3 only for a clearly defined download requirement
POP3 does not retain IMAP’s full folder and flag model. Client choices for “delete after download,” “leave a server copy,” and UIDL behavior determine the data risk. Use POP3S 995 or protected STARTTLS only if the provider still formally supports POP3 and the business specifically needs that model.
Before the first connection, prove with a test account whether the server copy remains, whether multiple devices duplicate downloads, how UID reset is handled, whether attachments and large messages are complete, whether retry duplicates mail, and how local data is retained after credential revocation. Reject every example that logs in over plaintext port 110, accepts any certificate, or deletes remote mail by default.
Moving from IMAP to POP3 is a data-model migration, not a port substitution. Do not switch without a server export, restorable backup, test matrix, and retirement plan.
Secrets, permissions, and logs
- Never put a password, app password, access/refresh token in command arguments, shell history, environment variables, screenshots, Git, or article configuration.
- Configuration, Maildir, synchronization state, OAuth cache, and keyring-access helpers are readable only by the dedicated account; backups also need encryption and access control.
- Prefer the smallest OAuth mail-read scope. If the provider cannot separate scopes, record the extra permission and have the owner accept the risk.
- Use an independently revocable app password only when the provider explicitly supports it; never reuse the primary password.
- Scheduled jobs use a separate service account, constrained network, and protected keyring; they must not depend on an unlocked personal desktop session.
- Do not enable network debugging that prints protocol bodies, authentication exchanges, messages, or attachments. Logs retain only time, channel, result code, and redacted counts by default.
- Mail can itself contain personal data, secrets, malicious HTML, and attachments; define local retention, deletion, forensics, and incident-response handling.
If a secret ever appears in arguments, terminal sharing, logs, or Git, stop synchronization, revoke the token/app password, inspect access records, and rotate it under the incident process. Deleting one file cannot remove leaked copies.
Failure classification and stop conditions
| Symptom | Non-secret evidence to collect first | Safe next step | Prohibited response |
|---|---|---|---|
| DNS/connection failure | Official hostname, resolution result, port, time, service status | Verify network and provider advisory | Try random IPs, proxies, or mirror endpoints |
| TLS validation failure | Hostname, certificate subject/expiry, validation error, system time | Fix DNS/time/CA or contact the administrator | Disable certificate or hostname validation |
| Authentication failure | Mechanism name, client version, provider error code, MFA/OAuth status | Stop retrying, check official policy, and revoke suspicious credentials | Use the primary password, copy cookies, expose a token |
| Missing folder | Redacted folder name, namespace, subscription status, permissions | List only first and compare provider semantics | Automatically create/delete all remote folders |
| Duplicate or UID change | Channel, state version, UIDVALIDITY, redacted counts | Freeze state and local replica; consult mbsync recovery guidance | Delete state and blindly rerun |
| Quota/throttling | Error code, time window, count and size totals | Reduce frequency and contact the provider | Concurrent loops or unlimited retry |
| Wrong local permissions | Numeric mode, owner, mount, backup policy | Stop reading and fix dedicated-directory access | Routine root operation or world-readable permissions |
Any step requiring TLS to be disabled, arbitrary certificates to be trusted, secrets to be written in configuration/arguments, another person’s account to be used, organizational policy to be bypassed, or deletions to propagate without backup is a stop condition.
Rollback, revocation, and offboarding
If the experiment fails, disable any scheduled job first and preserve read-only evidence of the configuration, synchronization state, log summary, and local Maildir. Do not delete remote content. Because the channel is Pull New, Remove None, and Expunge None, a normal experiment should not change the remote side, but verify this in the provider’s web interface.
An identified owner performs rollback: revoke the OAuth authorization or app password; remove the matching keyring entry; move the experiment directory into an access-controlled quarantine; restore the previous configuration; confirm that other clients still read mail; and use the retention policy to decide when local mail and state are destroyed. Never clean a mailbox with broad wildcards or confuse deleting a local replica with deleting provider data.
When a person leaves or a device is retired, revoke credentials and client registration, stop jobs, transfer business-mailbox ownership, verify audit logs, cryptographically erase local copies, and record completion evidence. A personal primary account must not become a permanent automation dependency.
Preproduction checklist
- Local system mailbox, IMAP, POP3, and SMTP responsibilities are distinguished.
- Host, port, authentication, quota, folder semantics, and client permission come from provider-authoritative documentation.
- TLS chain, hostname, and validity verification succeeds without downgrade or trust-all settings.
- OAuth has minimal, revocable scope, or an approved independent app password is used; the primary password is not used.
- Secrets are absent from arguments, environment, plaintext configuration, logs, screenshots, and Git.
- Client and dependencies come from supported software sources, and versions/features are recorded.
- The first test uses a dedicated account, seed messages, isolated directories, and
--dry-run. - Sync pulls only new mail and does not push, delete, or expunge until separately reviewed.
- Local directories, state, backups, and logs have least privilege and a defined retention period.
- Message integrity, remote non-change, throttling, failed retry, and restoration are verified.
- Monitoring, owner, stop conditions, credential revocation, rollback, and offboarding processes exist.
References
- POSIX/Open Group: `mailx` send and receive modes
- RFC 9051: IMAP4rev2
- RFC 8314: TLS for mail submission and access
- RFC 7628: SASL mechanisms for OAuth
- Official isync manual: `mbsync`
- NeoMutt: credential Account Command
- NeoMutt: IMAP and OAuth settings
- OpenSSL: `s_client` TLS diagnostics
Historical source archive
The following is the complete inert archive of the visible 2014 body in source_export, with no rewriting or trailing-whitespace changes beyond the privacy replacements. Six personal recipient-address occurrences became [historical recipient address redacted], and two personal home-directory occurrences became [historical home directory redacted]; the original values remain only in source_export and Git history. The HTTP attribution address remains unchanged inside the fence as provenance evidence and is not a current recommended link. The sending, attachment, installation, and repost commands inside the fence are obsolete and must never be executed.
在Linux系统下mail命令的测试
1. 最简单的一个例子:
mail -s test [historical recipient address redacted]
这条命令的结果是发一封标题为test的空信给后面的邮箱,如果你有mta并且后面的邮箱不会挡这种可能莫名奇妙的信的时候,就能收到这封信了。如果你不想被这种乱七八糟的事情干扰,后面的邮箱请使用本地帐户。
2. 第二个例子:
三种常用格式发信
mail -s test [historical recipient address redacted] #第一种方法,你可以把当前shell当成编辑器来用,编辑完内容后Ctrl-D结束
echo “mail content”|mail -s test [historical recipient address redacted] #第二种方法,我用的最多,可能是喜欢管道的缘故吧
mail -s test [historical recipient address redacted] < file #第三种方法,以file的内容为邮件内容发信
其实你很容易发现mail从标准输入读取文件内容并发信,我也只想让你知道这一点,到此,第二个例子结束。
3. 第三个例子,带附件的邮件
如果你的系统里没有uuencode命令的话,请先安装sharutils(yum install sharutils)
uuencode 需要两个参数,第一个是你要发送的文件(们),当然这个也可以用管道来做,第二个是显示的文件名
uuencode [historical home directory redacted]/a.gif a.gif|mail -s pictest [historical recipient address redacted]
tar czf – [historical home directory redacted]/ | uuencode home.tgz |mail -s pictest [historical recipient address redacted]
ps: 顺便补一句,slackware下的mail好像有一个-a参数,可以直接添加附件,我没有用过。
转自:http://www.svn8.com/linux/accidence/20091016/10858.html
