0

I am able to send emails in Linux via commandline:

cat < x.txt | mail -s "SUBJECT" email@email.com

This works perfectly. Note: The body is in x.txt.

Now, I want to execute exactly this command with Java.

Process p = Runtime.getRuntime().exec(
            new String[] { "cat < x.txt", "|", "mail -s", "SUBJECT",
                    "email@email.com" });

    p.waitFor();
    BufferedReader buf = new BufferedReader(new InputStreamReader(
            p.getInputStream()));
    String line = "";
    String output = "";

    while ((line = buf.readLine()) != null) {
        output += line + "\n";
    }

System.out.println(output);

Well, It is not working and I am getting following error.

Exception in thread "main" java.io.IOException: Cannot run program "cat < x.txt |": error=2, Datei oder Verzeichnis nicht gefunden
        at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
        at java.lang.Runtime.exec(Runtime.java:620)
        at java.lang.Runtime.exec(Runtime.java:485)
        at test.main(test.java:9) Caused by: java.io.IOException: error=2, Datei oder Verzeichnis nicht gefunden
        at java.lang.UNIXProcess.forkAndExec(Native Method)
        at java.lang.UNIXProcess.<init>(UNIXProcess.java:248)
        at java.lang.ProcessImpl.start(ProcessImpl.java:134)
        at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
        ... 3 more

Am I splitting those command(s) wrong?

How can I execute this command properly?

alexander
  • 1,191
  • 2
  • 20
  • 40

2 Answers2

6

Try to write a script and execute it, rather than execute separate commands:

String email = "email@email.com"; // Or any way of entering the email address
String[] command = {"/bin/sh", "-c", "cat < x.txt | mail -s SUBJECT" +  email};
Process p = Runtime.getRuntime().exec(command);

Pipe (|) is a shell built-in, and not an actual unix command as such.

EvenLisle
  • 4,672
  • 3
  • 24
  • 47
  • Okay, thank you for the hint. Unfortunately I need to pass the email as param from java. Is there any chance to do this? – alexander Apr 18 '15 at 11:54
  • So sorry, I didn't change the code to fit your example. Updated the answer. – EvenLisle Apr 18 '15 at 11:59
  • Well, no one said that. I asked about any chance, not about code. A hint was enough. Well, I found an other solution, without pipe. Thanks anyway, you opened my eyes! :) And sorry, I am not familiar with linux and those commands. – alexander Apr 18 '15 at 14:03
0

You should probably be doing something like:

Process p = Runtime.getRuntime().exec("/usr/sbin/sendmail .. email@email.com");
OutputStream os = p.getOutputStream();
InputStream is = new FileInputStream("x.txt");
// copy the contents
byte[] buf = new byte[4096];
int len;
while ((len = is.read(buf)) != -1) {
    os.write(buf, 0, len); // only write as many as you have read
}
os.close();
is.close();

Also note, you have javamail api already available, so make sure you make your code platform independent by using such libraries.

SMA
  • 36,381
  • 8
  • 49
  • 73