how to send a mail with a message in unix script
Stefan Bogdanescu
Founder & Senior Architect
Sending Emails Programmatically in Unix Scripts: Including Full Messages
Welcome to the world of shell scripting! Learning the "talk and walk" of Unix commands is fundamental to system administration and automation. When you move from simple commands to building complex scripts, managing input and output streams becomes a key skill.
You are encountering a common hurdle when working with tools like mailx or the older mail command: they are designed to prompt the user interactively for the message body if no input is piped to them. Your goal—to pre-include the message content directly within your script—is entirely achievable, and it requires understanding how standard input (stdin) works in Unix environments.
As a senior developer, we need methods that are not only functional but also robust and scalable. Let’s dive into the best ways to send emails with complete messages from your .ksh script.
Understanding the mailx Interaction Problem
Your current command:
mailx -s"File not found" abc@def.com
This command is missing the actual message body. When you run it without piping content, mailx pauses and waits for you to type the subject and recipient details interactively, but critically, it also waits for the body of the email, prompting you to enter it separately.
To solve this, we need to feed the entire message—subject line and body—into the command via standard input redirection, bypassing the interactive prompt.
Method 1: Using Here Documents (The Cleanest Approach)
The most elegant and recommended way to pass multi-line text directly into a command that expects input is by using a Here Document (<<). This method allows you to define a block of text within your script, and the shell redirects that entire block as input to the subsequent command.
Here is how you can modify your script to include the full message:
#!/bin/ksh
# Define variables for clarity
RECIPIENT="abc@def.com"
SUBJECT="File not found"
# Use a Here Document (<<) to provide the email content as input
mailx -s"${SUBJECT}" "${RECIPIENT}" <<EOF
This is the detailed message body for the file operation.
The script executed successfully, but we encountered an error finding the specified file.
Please review the logs for further details.
--- End of Message ---
Script execution time: $(date)
EOF
Explanation of the Code:
mailx -s"${SUBJECT}" "${RECIPIENT}": We set the necessary headers (subject and recipient).<<EOF: This signals the shell that everything following is the content for this command until it encounters a line containing onlyEOF. The content between the markers becomes the standard input formailx.
This approach ensures that the entire message, including multiple lines and special characters, is delivered as one cohesive unit without any interactive pauses.
Method 2: Redirection via a Temporary File (The Robust Approach)
For very complex messages, or when dealing with extreme error handling, writing the content to a temporary file first is often more robust. This method separates the message generation from the mailing action, making debugging easier.
#!/bin/ksh
RECIPIENT="abc@def.com"
SUBJECT="File not found"
MESSAGE_FILE=$(mktemp) # Create a secure temporary file
# Write the entire message to the temporary file
cat > "$MESSAGE_FILE" << MESSAGE_BODY
This is the detailed message body for the file operation.
The script executed successfully, but we encountered an error finding the specified file.
Please review the logs for further details.
--- End of Message ---
Script execution time: $(date)
MESSAGE_BODY
# Note: The final line must be EXACTLY MESSAGE_BODY to close the redirection correctly if using this structure.
# Send the email by piping the file contents into mailx
mailx -s"${SUBJECT}" "${RECIPIENT}" < "$MESSAGE_FILE"
# Clean up the temporary file
rm "$MESSAGE_FILE"
Conclusion: Scripting for Efficiency
By mastering input/output redirection techniques like Here Documents, you transform your shell scripts from simple command executors into powerful automation tools. This practice is central to writing efficient, maintainable system scripts. Whether you are automating infrastructure tasks or managing complex application flows—much like structuring services in a framework like Laravel requires careful attention to data flow and communication—the principle remains the same: define your input clearly and feed it efficiently to the system.
Always strive for methods that minimize interaction and maximize automation, ensuring your scripts run silently and reliably every time.
Note: Blog content is currently available in English.