Friday, October 22, 2010

How to use Unix shell script to send e-mail.

Recently, got problem to send e-mail from Unix with an existing shell script. It took me a long time to fixed. Here is the implementation of mine.

1. Mail sender



import java.io.BufferedReader;
import java.io.InputStreamReader;

public class MailSender {

public void send() throws Exception {
String[] cmd = { "sh", "/opt/app/test/SendEmail.sh",
"Victor Mail Sender", "hello Victor!", "mail@victor.net",
"victor@gmail.com" };

Runtime rt = Runtime.getRuntime();

Process p = rt.exec(cmd);

BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(p.getInputStream()));
String x = null;
while ((x = br.readLine()) != null) {
System.out.println(x);
}
p.waitFor();
} finally {
try {
if (br != null)
br.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

public static void main(String[] args) {
try {
MailSender ms = new MailSender();
ms.send();
} catch (Exception e) {
e.printStackTrace();
}
}
}


In the above code, when we build the command used to send mail, we use "sh" as the first value of string array. If without this value, the SendEmail.sh must be set an executable permission. Using array to execute the shell script is to allow space in the subject and message body. If you put them in a string as a command to execute, it will not work and all the space in the command will be used as a separator.

The follow info is copied from The Java Developers Almanac.


     try {
       // Execute a command without arguments
       String command = "ls";
       Process child = Runtime.getRuntime().exec(command);
 
       // Execute a command with an argument
       command = "ls /tmp";
       child = Runtime.getRuntime().exec(command);
   } catch (IOException e) {
   }

   //If an argument contain spaces, it is necessary to use the overload that requires the command and its arguments to be supplied in an array:
   try {
       // Execute a command with an argument that contains a space
       String[] commands = new String[]{"grep", "hello world", "/tmp/f.txt"};
       commands = new String[]{"grep", "hello world", "c:\\Documents and Settings\\f.txt"};
       Process child = Runtime.getRuntime().exec(commands);
   } catch (IOException e) {
   }


Unix Shell Scirpt:


#!/usr/bin/ksh

# --------------------------
# 1, Set up environment
# --------------------------

LOG_HIS="./Mail.History.log"

#Current environment variable
TS=$(date +%Y%m%d-%H%M%S)

# ------------------------------------------------------------
# 2, Check parameter and write initial info into log
# ------------------------------------------------------------
echo "--------------------------- ${TS} -------------------------- "  >>${LOG_HIS}

# Check if has parameter
if [ "$#" -lt 4 ]
then
    echo "Error: Missed parameters !" >> ${LOG_HIS}
    exit 1
else
    from=$3
    to=$4
    Subject=$1
    body=$2
    
    echo "Subject:  ${Subject}" >> ${_LOG_HIS}
    echo "body:  ${body}" >> ${LOG_HIS}
    echo "From:  ${from}" >> ${LOG_HIS}
    echo "To:  ${to}" >> ${LOG_HIS}
fi

echo  $body |mailx -m -r $from -s "$Subject"  $to >> ${LOG_HIS}

exit 0

No comments: