BLOG POSTS
    MangoHost Blog / Send Email from Linux Command Line – Quick Tutorial
Send Email from Linux Command Line – Quick Tutorial

Send Email from Linux Command Line – Quick Tutorial

Sending emails directly from the Linux command line is a crucial skill for developers and system administrators who need to automate notifications, create backup alerts, or integrate email functionality into scripts. Whether you’re setting up monitoring systems, scheduling reports, or troubleshooting server issues remotely, knowing how to fire off emails without a GUI can save you tons of time and enable powerful automation workflows. This tutorial will walk you through multiple methods to send emails from Linux, covering everything from simple one-liners to advanced SMTP configurations, along with real-world examples and troubleshooting tips you’ll actually use.

How Email Sending Works on Linux

Linux systems can send emails through several mechanisms. The most common approach uses a Mail Transfer Agent (MTA) like sendmail, postfix, or exim that handles the actual email delivery. Alternatively, you can use lightweight utilities that connect directly to external SMTP servers without running a full MTA locally.

The basic flow works like this:

  • Your command or script generates email content
  • A mail utility formats the message according to email standards
  • The message gets passed to either a local MTA or external SMTP server
  • The server handles routing and delivery to the recipient

For most scenarios, you’ll choose between using the system’s built-in mail command (requires local MTA setup) or external tools like msmtp or swaks that can work with Gmail, Office 365, or other SMTP providers.

Method 1: Using the Built-in Mail Command

The traditional mail command is available on most Linux distributions, though you might need to install mailutils or similar packages first.

# Install mail utilities (Ubuntu/Debian)
sudo apt-get install mailutils

# Install mail utilities (CentOS/RHEL)
sudo yum install mailx

Basic usage is straightforward:

# Simple email
echo "This is the email body" | mail -s "Subject Line" recipient@example.com

# Email with file content
mail -s "Server Report" admin@company.com < /var/log/backup.log

# Multiple recipients
echo "Alert message" | mail -s "System Alert" -c cc@example.com -b bcc@example.com primary@example.com

For more complex emails with headers:

# Email with custom headers
mail -s "Automated Report" -a "From: monitoring@yourserver.com" recipient@example.com << EOF
This is a multi-line email body.

It can contain multiple paragraphs
and formatting.

Best regards,
Your Server
EOF

Method 2: Using msmtp for External SMTP

msmtp is a lightweight SMTP client that's perfect when you don't want to run a full MTA but need to send through external providers like Gmail or Office 365.

# Install msmtp
sudo apt-get install msmtp msmtp-mta

Create the configuration file:

# ~/.msmtprc
defaults
auth           on
tls            on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
logfile        ~/.msmtp.log

# Gmail configuration
account        gmail
host           smtp.gmail.com
port           587
from           your-email@gmail.com
user           your-email@gmail.com
password       your-app-password

# Office 365 configuration
account        office365
host           smtp.office365.com
port           587
from           your-email@company.com
user           your-email@company.com
password       your-password

# Set default account
account default : gmail

Set proper permissions:

chmod 600 ~/.msmtprc

Now you can send emails:

# Using msmtp directly
echo "Email body" | msmtp recipient@example.com

# Using with mail command
echo "Email body" | mail -s "Subject" recipient@example.com

Method 3: Using swaks for Testing and Advanced Scenarios

swaks (Swiss Army Knife for SMTP) is excellent for testing SMTP servers and sending emails with specific requirements.

# Install swaks
sudo apt-get install swaks

Basic usage examples:

# Simple email via external SMTP
swaks --to recipient@example.com --from sender@example.com --server smtp.gmail.com:587 --auth-user sender@gmail.com --auth-password app-password --tls

# Email with attachment
swaks --to recipient@example.com --from sender@example.com --attach @/path/to/file.pdf --server smtp.gmail.com:587 --auth-user sender@gmail.com --auth-password app-password --tls

# HTML email
swaks --to recipient@example.com --from sender@example.com --header "Content-Type: text/html" --body '

HTML Email

This is bold text.

' --server smtp.gmail.com:587 --auth-user sender@gmail.com --auth-password app-password --tls

Real-World Examples and Use Cases

Here are practical scripts you can use immediately:

System Monitoring Alert

#!/bin/bash
# disk-alert.sh - Monitor disk usage and send alerts

THRESHOLD=80
DISK_USAGE=$(df -h / | awk 'NR==2 {print $5}' | sed 's/%//')

if [ $DISK_USAGE -gt $THRESHOLD ]; then
    MESSAGE="Warning: Disk usage is at ${DISK_USAGE}%
    
Server: $(hostname)
Time: $(date)
    
Please investigate immediately."
    
    echo "$MESSAGE" | mail -s "URGENT: Disk Space Alert - $(hostname)" admin@company.com
fi

Backup Completion Notification

#!/bin/bash
# backup-notify.sh - Send backup completion status

BACKUP_LOG="/var/log/backup.log"
BACKUP_SIZE=$(du -sh /backup | cut -f1)

if [ $? -eq 0 ]; then
    STATUS="SUCCESS"
    SUBJECT="Backup Completed Successfully"
else
    STATUS="FAILED"
    SUBJECT="BACKUP FAILURE - Immediate Action Required"
fi

cat << EOF | mail -s "$SUBJECT" -a "X-Priority: 1" backup-admin@company.com
Backup Status: $STATUS
Backup Size: $BACKUP_SIZE
Server: $(hostname)
Completed: $(date)

Log details:
$(tail -20 $BACKUP_LOG)
EOF

SSL Certificate Expiry Checker

#!/bin/bash
# ssl-check.sh - Check SSL certificate expiration

DOMAIN="yourdomain.com"
EXPIRY_DATE=$(echo | openssl s_client -servername $DOMAIN -connect $DOMAIN:443 2>/dev/null | openssl x509 -noout -dates | grep notAfter | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
CURRENT_EPOCH=$(date +%s)
DAYS_UNTIL_EXPIRY=$(( (EXPIRY_EPOCH - CURRENT_EPOCH) / 86400 ))

if [ $DAYS_UNTIL_EXPIRY -lt 30 ]; then
    swaks --to ssl-admin@company.com \
          --from monitoring@$DOMAIN \
          --header "Subject: SSL Certificate Expiring Soon - $DOMAIN" \
          --body "SSL certificate for $DOMAIN expires in $DAYS_UNTIL_EXPIRY days ($EXPIRY_DATE). Please renew immediately." \
          --server smtp.gmail.com:587 \
          --auth-user monitoring@company.com \
          --auth-password $SMTP_PASSWORD \
          --tls
fi

Comparison of Email Methods

Method Setup Complexity External SMTP Attachments HTML Support Best For
mail command Medium No (requires MTA) Limited Limited Simple notifications, local delivery
msmtp Low Yes Via mail command Yes Production scripts, Gmail/Office365
swaks Low Yes Yes Yes Testing, advanced formatting
sendmail/postfix High Optional Yes Yes High-volume, complex routing

Best Practices and Security Considerations

Follow these practices to avoid common issues:

  • Never hardcode passwords: Use environment variables or secure credential storage
  • Use app passwords: For Gmail and Office 365, generate application-specific passwords instead of using your main password
  • Enable TLS: Always encrypt SMTP connections when using external providers
  • Set proper file permissions: Configuration files with passwords should be 600 (-rw-------)
  • Test thoroughly: Use swaks to verify SMTP settings before deploying scripts
  • Handle failures gracefully: Check return codes and implement retry logic for critical notifications
  • Rate limiting: Be mindful of SMTP provider limits to avoid getting blocked

Example of secure credential handling:

#!/bin/bash
# secure-email.sh - Using environment variables for credentials

# Set these in your environment or .bashrc
# export SMTP_USER="your-email@gmail.com"
# export SMTP_PASS="your-app-password"

if [ -z "$SMTP_USER" ] || [ -z "$SMTP_PASS" ]; then
    echo "Error: SMTP credentials not set in environment variables"
    exit 1
fi

echo "Alert message" | msmtp --account=gmail recipient@example.com

Troubleshooting Common Issues

Here are solutions to problems you'll likely encounter:

Authentication Failures

# Test SMTP authentication
swaks --to test@example.com --from $SMTP_USER --server smtp.gmail.com:587 --auth-user $SMTP_USER --auth-password $SMTP_PASS --tls --auth-test

Common causes:

  • Using regular password instead of app password for Gmail
  • Two-factor authentication not properly configured
  • Less secure app access disabled in Gmail settings

TLS/SSL Issues

# Test TLS connection
openssl s_client -starttls smtp -connect smtp.gmail.com:587

# Check certificate bundle location
ls -la /etc/ssl/certs/ca-certificates.crt

Mail Command Not Working

# Check if local MTA is running
sudo systemctl status postfix
# or
sudo systemctl status sendmail

# Check mail queue
mailq

# Test local delivery
echo "test" | mail -s "test" $USER

Character Encoding Problems

# Force UTF-8 encoding
export LC_ALL=en_US.UTF-8
echo "Special chars: äöü" | mail -s "=?UTF-8?B?$(echo -n "Test Subject äöü" | base64)?=" recipient@example.com

Advanced Integration Examples

Combine email functionality with system monitoring tools:

# Integration with systemd services
# /etc/systemd/system/backup-notify.service
[Unit]
Description=Backup Notification Service
After=backup.service

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup-notify.sh
User=backup
Environment=SMTP_USER=monitoring@company.com
EnvironmentFile=/etc/backup/smtp.env

[Install]
WantedBy=multi-user.target

Cron job with error handling:

# crontab entry
0 2 * * * /usr/local/bin/backup-with-email.sh 2>&1 | logger -t backup-cron

For more detailed information on SMTP configuration and mail server setup, check the official documentation for msmtp and swaks.

These methods will cover virtually any email-sending scenario you'll encounter on Linux systems. Start with msmtp for most production use cases, use swaks for testing and troubleshooting, and fall back to the traditional mail command when you need tight integration with existing MTA setups.



This article incorporates information and material from various online sources. We acknowledge and appreciate the work of all original authors, publishers, and websites. While every effort has been made to appropriately credit the source material, any unintentional oversight or omission does not constitute a copyright infringement. All trademarks, logos, and images mentioned are the property of their respective owners. If you believe that any content used in this article infringes upon your copyright, please contact us immediately for review and prompt action.

This article is intended for informational and educational purposes only and does not infringe on the rights of the copyright owners. If any copyrighted material has been used without proper credit or in violation of copyright laws, it is unintentional and we will rectify it promptly upon notification. Please note that the republishing, redistribution, or reproduction of part or all of the contents in any form is prohibited without express written permission from the author and website owner. For permissions or further inquiries, please contact us.

Leave a reply

Your email address will not be published. Required fields are marked