Send Email From Linux CLI Without Running a Full Mail Server
A compact hosting-admin guide to sending scripted alerts with msmtp or mail while keeping SMTP credentials locked down and avoiding a full local mail server.
Server email does not have to mean operating a full mail platform. For many hosting tasks, the goal is smaller: send a cron result, backup alert, certificate warning, or monitoring note through an authenticated SMTP relay. DigitalOcean’s updated Linux email tutorial covers common command-line tools, but the safest hosting pattern is to keep the relay configuration small and auditable. DigitalOcean’s guide was updated in June 2026 and covers mail, mutt, sendmail-style flows, and msmtp.
Table Of Content
- Use a relay-first tool for scripted alerts
- Send a simple test message
- Use mail only after the transport is configured
- When to use a real local MTA
- Hosting-admin checklist
- Relay-first alerting runbook for cron and systemd jobs
- Target system: Ubuntu/Debian alert sender
- Target system: RHEL-family alert sender with a repository that provides msmtp
- Config target: sending user’s ~/.msmtprc
- Target system: same Linux user that will send the alert
- Target system: same Linux user that will send the alert
- Target system: Ubuntu/Debian or RHEL-family host, checking local sender logs
- How to wire the mail command into scheduled jobs safely
- Target system: systemd service or timer running as a dedicated Linux user
- Target system: cron job using explicit paths
Use a relay-first tool for scripted alerts
For a lightweight server, msmtp is often the cleanest fit: it reads a message from standard input and submits it to an SMTP server instead of trying to receive mail for your domain. The msmtp manual documents account configuration, TLS options, and password lookup helpers such as passwordeval. The msmtp manual documents its configuration file and SMTP options.
defaults
auth on
tls on
tls_starttls on
logfile ~/.msmtp.log
account alerts
host smtp.example.com
port 587
from [email protected]
user [email protected]
passwordeval "pass show smtp/alerts"
account default : alerts
Keep the configuration readable only by the account that sends mail, especially if it references credentials or credential helpers.
chmod 600 ~/.msmtprc
Send a simple test message
msmtp accepts the recipient on the command line and reads the full message, including headers, from standard input. That makes it easy to test from a shell before wiring it into a cron job or systemd timer. Ubuntu’s msmtp man page documents the command-line behavior.
printf 'Subject: test alert
The Linux alert path works.
' | msmtp [email protected]
Use mail only after the transport is configured
The traditional mail interface is convenient for scripts that need a subject flag and a short body, but it is only the front-end command. On a fresh server, mail still needs a working local MTA, a sendmail-compatible relay wrapper, or its own SMTP configuration; it does not automatically inherit ~/.msmtprc just because msmtp is installed. On Ubuntu, the mailutils man page documents the -s subject option, but you should send a real test message through the configured transport before relying on it for cron alerts. Ubuntu’s mailutils man page documents the mail command interface.
printf 'Backup finished on %s
' "$(hostname)" | mail -s 'Nightly backup status' [email protected]
When to use a real local MTA
If you need local queuing, retries, domain delivery, aliases, or policy controls, a real MTA such as Postfix is the more appropriate tool. Postfix’s own basic-configuration documentation is the authoritative place to start before exposing or relaying mail from a production host. Postfix documents the basic configuration model for production mail handling.
Hosting-admin checklist
- Use a dedicated SMTP account for alerts, not a personal mailbox.
- Prefer a credential helper or root-owned secret over plaintext passwords in scripts.
- Send a test message after package updates and after credential rotation.
- Log delivery attempts, but do not log passwords or message contents unnecessarily.
- Use a full MTA only when you actually need queueing or inbound mail behavior.
Relay-first alerting runbook for cron and systemd jobs
This section applies to a Linux server that only needs to send outbound operational mail through an authenticated SMTP relay. It is not a design for receiving mail, queueing domain mail, or operating MX records. Before installing anything, collect the relay hostname, port, username, allowed envelope/from address, credential method, recipient address, and whether outbound TCP 587 is permitted by the host firewall or cloud provider.
Target system: Ubuntu/Debian alert sender
sudo apt update
sudo apt install msmtp msmtp-mta ca-certificates
Target system: RHEL-family alert sender with a repository that provides msmtp
sudo dnf install msmtp ca-certificates
Use the package set that matches the target system. On Debian/Ubuntu, msmtp-mta provides a sendmail-compatible interface for local programs that expect /usr/sbin/sendmail. On a cPanel/WHM server, do not replace the platform mail stack casually; WHM uses Exim, and mail troubleshooting should normally go through Exim Configuration Manager, Mail Delivery Reports, and the existing sendmail-compatible path. cPanel Exim Configuration Manager cPanel Mail Delivery Reports
Config target: sending user’s ~/.msmtprc
defaults
auth on
tls on
tls_starttls on
logfile ~/.msmtp.log
account alerts
host smtp.example.com
port 587
from [email protected]
user [email protected]
passwordeval "pass show smtp/alerts"
account default : alerts
The msmtp manual documents account configuration, TLS options, logging, and password lookup helpers such as passwordeval. msmtp manual Keep the file readable only by the sending account. If the script runs as root, configure root’s file. If it runs as a service user such as backup, configure that user’s home directory instead. Many alerting failures are not SMTP failures at all; they happen because cron or systemd runs as a different user with a different HOME.
Target system: same Linux user that will send the alert
chmod 600 ~/.msmtprc
msmtp --serverinfo --host=smtp.example.com --port=587 --tls=on --tls-starttls=on
--serverinfo verifies that the server is reachable and advertises expected SMTP capabilities. It does not prove that your final From address is accepted, so send a real message next.
Target system: same Linux user that will send the alert
printf 'From: [email protected]
To: [email protected]
Subject: msmtp relay test
Relay path works from this host.
' | msmtp --debug [email protected]
Target system: Ubuntu/Debian or RHEL-family host, checking local sender logs
tail -n 50 ~/.msmtp.log
journalctl -n 50 --no-pager
Common failure modes are predictable. 535 usually means bad credentials or a provider that requires an app password. 550 or “relaying denied” usually means the account is not allowed to send as the configured From address or to that recipient. TLS verification errors point to a missing CA bundle, interception, or the wrong relay hostname. Silent cron failures usually mean the command worked interactively but ran under a different user, with a different path, no password helper session, or no readable ~/.msmtprc. After a credential rotation, repeat the debug send and check the relay’s delivery log or provider dashboard; a local “sent” result only proves submission to the relay, not inbox placement. The Ubuntu msmtp man page documents command-line behavior for msmtp on Ubuntu systems, while mailutils documents the traditional mail interface for scripts that call a mail front end. Ubuntu msmtp man page Ubuntu mailutils man page
How to wire the mail command into scheduled jobs safely
The final test is not an interactive shell. It is the exact environment that will send the alert. Cron, systemd timers, backup scripts, and monitoring hooks often run with a reduced PATH, a different HOME, and no interactive password helper. That is why a message can work as your login user and fail silently from automation.
Target system: systemd service or timer running as a dedicated Linux user
# /etc/systemd/system/example-alert.service
[Service]
Type=oneshot
User=backup
Environment=HOME=/home/backup
ExecStart=/usr/local/bin/send-backup-alert
If the service runs as backup, then /home/backup/.msmtprc, its credential helper, and its log file must be readable by that account. If the service runs as root, root’s configuration is used instead. Do not assume that the relay settings from your interactive account are inherited.
Target system: cron job using explicit paths
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MAILTO=""
15 2 * * * /usr/local/bin/nightly-backup 2>&1 | /usr/bin/msmtp [email protected]
This example is deliberately explicit about command paths. If you use mail instead of msmtp, verify which transport the mail command invokes on that system. On cPanel/WHM, that transport may be Exim. On a minimal VPS, it may be absent until you install a local MTA or sendmail-compatible wrapper. The operational rule is the same across systems: send one real test from the exact scheduled context, then check the local log and the upstream relay’s delivery report before trusting the alert path.
Featured image: gajman, “Message to the mail man,” via Flickr, licensed under CC BY 2.0.








No Comment! Be the first one.