When migrating between servers with different mail utilities, many sysadmins encounter the frustrating difference between mail
and sendmail
command syntax. The particular challenge comes when trying to:
- Pipe command output to email
- Set a custom subject line
- Maintain error output (2>&1)
- Do it without modifying original scripts
The mail
command commonly accepts the subject flag -s
directly:
command | mail -s "Subject" recipient@domain.com
But sendmail
expects email headers in the piped content itself. Here's why your current approach fails:
/usr/local/bin/php -f file.php 2>&1 | /usr/sbin/sendmail -s "Subject" test@email.com
# The -s flag doesn't work as expected with sendmail
To properly format email headers when piping to sendmail:
/usr/local/bin/php -f /path/to/file.php 2>&1 | (
echo "Subject: My Test Email Subject"
echo "To: test@email.com"
echo "Content-Type: text/plain; charset=UTF-8"
echo
cat
) | /usr/sbin/sendmail -t
1. Command Subshell: The parentheses create a subshell to process headers and content
2. Email Headers: We explicitly define:
- Subject line
- Recipient (To: field)
- Content type
3. Empty Line: Critical separator between headers and body
4. cat: Passes through the piped content as email body
5. -t flag: Tells sendmail to extract recipients from headers
1. Adding CC and From fields:
command | (
echo "From: cron@server.com"
echo "To: admin@domain.com"
echo "Cc: team@domain.com"
echo "Subject: Daily Backup Report"
echo "Content-Type: text/plain; charset=UTF-8"
echo
cat
) | sendmail -t
2. HTML formatted email:
command | (
echo "To: user@domain.com"
echo "Subject: HTML Report"
echo "Content-Type: text/html; charset=UTF-8"
echo "MIME-Version: 1.0"
echo
echo "<html><body>"
echo "<h1>Report Output</h1>"
echo "<pre>"
cat
echo "</pre>"
echo "</body></html>"
) | sendmail -t
Problem: Email arrives with empty body
Fix: Ensure there's exactly one empty line between headers and body
Problem: Special characters appear broken
Fix: Set proper charset in Content-Type header
Problem: Email goes to spam
Fix: Add proper From header and consider SPF/DKIM configuration
When moving scripts from systems using the basic mail
command to those using sendmail
, one common pain point is properly formatting email subjects when piping command output. Many legacy cron jobs and automated scripts rely on this functionality for notifications.
The sendmail
command has different parameter requirements than mail
. For piping output with a subject, the correct syntax is:
command | sendmail -f "from@domain.com" -t <<EOF
To: recipient@email.com
Subject: Your Custom Subject Here
$(cat)
EOF
For your specific case of piping PHP script output, here's the working version:
/usr/local/bin/php -f /path/to/file.php 2>&1 | sendmail -f "cron@yourserver.com" -t <<EOF
To: test@email.com
Subject: My Test Email Subject
$(cat)
EOF
-f flag: Sets the envelope sender address (important for SPF/DKIM)
-t flag: Tells sendmail to read recipients from message headers
Here document (EOF): Allows embedding the email headers and body
If you encounter issues, try these troubleshooting steps:
# Test sendmail availability
which sendmail
# Verify permissions
ls -la /usr/sbin/sendmail
# Check mail queue
mailq
If available on your system, mailx
provides a simpler syntax:
/usr/local/bin/php -f /path/to/file.php 2>&1 | mailx -s "My Subject" test@email.com