正在从 Java Runtime.getRuntime 执行 linux mutt 不发送邮件也不报错
Executing linux mutt from Java Runtime.getRuntime not sending mail and not giving error
我尝试在 linux 和 java 中使用 mutt 发送电子邮件
如果我从 linux 命令行执行 mutt 命令,电子邮件发送很棒
echo "test" | mutt -s "subject" -- "jojo@foo.com
现在我有了这个简单的 java 应用程序,我尝试执行相同的命令但我什么也没得到,甚至没有错误:
java -cp runtime-SNAPSHOT.jar MyApp "echo \"test\" | mutt -s \"subject\" \"jojo@foo.com\""
class StreamGobbler extends Thread
{
InputStream is;
String type;
StreamGobbler(InputStream is, String type)
{
this.is = is;
this.type = type;
}
public void run()
{
try
{
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line=null;
while ( (line = br.readLine()) != null)
System.out.println(type + ">" + line);
} catch (IOException ioe)
{
ioe.printStackTrace();
}
}
}
public class MyApp {
public static void main(String[] args) throws InterruptedException, IOException {
if (args.length < 1)
{
System.out.println("USAGE: java GoodWindowsExec <cmd>");
System.exit(1);
}
try
{
String[] cmd = new String[3];
Runtime rt = Runtime.getRuntime();
System.out.println("Execing " + args[0] );
Process proc = rt.exec(args[0]);
// any error message?
StreamGobbler errorGobbler = new
StreamGobbler(proc.getErrorStream(), "ERROR");
// any output?
StreamGobbler outputGobbler = new
StreamGobbler(proc.getInputStream(), "OUTPUT");
// kick them off
errorGobbler.start();
outputGobbler.start();
// any error???
int exitVal = proc.waitFor();
System.out.println("ExitValue: " + exitVal);
} catch (Throwable t)
{
t.printStackTrace();
}
}
这里有什么问题?
您没有收到任何错误消息,因为 echo 似乎在您的系统上可用(通常为“/bin/echo”)。 Runtime exec 方法中的 Stringtokenizer 将您行的其余部分作为参数传递给 /bin/echo,如下所示:
/bin/echo "\"test\"" "|" "mutt" "-s" "\"subject\"" "--" "\"jojo@foo.com\""
嗯,这是一个有效的命令,因为它调用 /bin/echo 并且 /bin/echo 输出所有参数,但从不调用 mutt。 (顺便说一下,/bin/echo 与 Bash shell 中使用的回声不同,后者是内置函数,行为略有不同......)
他们(Java)在 exec 方法中标记命令有时可能很方便,但会导致像这样的相当恼人的效果,因为它让人假设某些东西应该起作用,但实际上并不像这种情况...
您可能想要的是 shell 执行命令行。所以你必须实际执行一个shell(我在文件中标记了更改):
public class MyApp {
static class StreamGobbler extends Thread {
InputStream is;
String type;
StreamGobbler(InputStream is, String type) {
this.is = is;
this.type = type;
}
public void run() {
try {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(type + ">" + line);
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException, IOException {
/*if (args.length < 1) {
System.out.println("USAGE: java GoodWindowsExec <cmd>");
System.exit(1);
}*/
args = new String[]{"echo \"test\" | grep -i \"s\" " };
try {
String[] cmd = new String[3];
Runtime rt = Runtime.getRuntime();
System.out.println("Execing " + args[0]);
//Change here: execute a shell with the command line instead of echo:
Process proc = rt.exec(new String[]{"/bin/sh","-c", args[0]});
// any error message?
StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), "ERROR");
// any output?
StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), "OUTPUT");
// kick them off
errorGobbler.start();
outputGobbler.start();
// any error???
int exitVal = proc.waitFor();
System.out.println("ExitValue: " + exitVal);
} catch (Throwable t) {
t.printStackTrace();
}
}
}
旁注。为了更好的最小测试用例:
- 我用一些 grep 替换了你的 mutt 命令,因为我不想发送邮件;)
我通过以编程方式创建数组 ("args") 伪造了 java 命令行。
使您的 StreamGobbler 静态化以便将其作为一个文件。
所有这些都不应该改变您的测试用例。真正不同的是执行 shell 而不是 /bin/echo
的 rt.exec 调用
示例运行:
Execing echo "test" | grep -i "s"
ExitValue: 0
OUTPUT>test
我尝试在 linux 和 java 中使用 mutt 发送电子邮件 如果我从 linux 命令行执行 mutt 命令,电子邮件发送很棒
echo "test" | mutt -s "subject" -- "jojo@foo.com
现在我有了这个简单的 java 应用程序,我尝试执行相同的命令但我什么也没得到,甚至没有错误:
java -cp runtime-SNAPSHOT.jar MyApp "echo \"test\" | mutt -s \"subject\" \"jojo@foo.com\""
class StreamGobbler extends Thread
{
InputStream is;
String type;
StreamGobbler(InputStream is, String type)
{
this.is = is;
this.type = type;
}
public void run()
{
try
{
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line=null;
while ( (line = br.readLine()) != null)
System.out.println(type + ">" + line);
} catch (IOException ioe)
{
ioe.printStackTrace();
}
}
}
public class MyApp {
public static void main(String[] args) throws InterruptedException, IOException {
if (args.length < 1)
{
System.out.println("USAGE: java GoodWindowsExec <cmd>");
System.exit(1);
}
try
{
String[] cmd = new String[3];
Runtime rt = Runtime.getRuntime();
System.out.println("Execing " + args[0] );
Process proc = rt.exec(args[0]);
// any error message?
StreamGobbler errorGobbler = new
StreamGobbler(proc.getErrorStream(), "ERROR");
// any output?
StreamGobbler outputGobbler = new
StreamGobbler(proc.getInputStream(), "OUTPUT");
// kick them off
errorGobbler.start();
outputGobbler.start();
// any error???
int exitVal = proc.waitFor();
System.out.println("ExitValue: " + exitVal);
} catch (Throwable t)
{
t.printStackTrace();
}
}
这里有什么问题?
您没有收到任何错误消息,因为 echo 似乎在您的系统上可用(通常为“/bin/echo”)。 Runtime exec 方法中的 Stringtokenizer 将您行的其余部分作为参数传递给 /bin/echo,如下所示:
/bin/echo "\"test\"" "|" "mutt" "-s" "\"subject\"" "--" "\"jojo@foo.com\""
嗯,这是一个有效的命令,因为它调用 /bin/echo 并且 /bin/echo 输出所有参数,但从不调用 mutt。 (顺便说一下,/bin/echo 与 Bash shell 中使用的回声不同,后者是内置函数,行为略有不同......)
他们(Java)在 exec 方法中标记命令有时可能很方便,但会导致像这样的相当恼人的效果,因为它让人假设某些东西应该起作用,但实际上并不像这种情况...
您可能想要的是 shell 执行命令行。所以你必须实际执行一个shell(我在文件中标记了更改):
public class MyApp {
static class StreamGobbler extends Thread {
InputStream is;
String type;
StreamGobbler(InputStream is, String type) {
this.is = is;
this.type = type;
}
public void run() {
try {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(type + ">" + line);
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException, IOException {
/*if (args.length < 1) {
System.out.println("USAGE: java GoodWindowsExec <cmd>");
System.exit(1);
}*/
args = new String[]{"echo \"test\" | grep -i \"s\" " };
try {
String[] cmd = new String[3];
Runtime rt = Runtime.getRuntime();
System.out.println("Execing " + args[0]);
//Change here: execute a shell with the command line instead of echo:
Process proc = rt.exec(new String[]{"/bin/sh","-c", args[0]});
// any error message?
StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), "ERROR");
// any output?
StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), "OUTPUT");
// kick them off
errorGobbler.start();
outputGobbler.start();
// any error???
int exitVal = proc.waitFor();
System.out.println("ExitValue: " + exitVal);
} catch (Throwable t) {
t.printStackTrace();
}
}
}
旁注。为了更好的最小测试用例:
- 我用一些 grep 替换了你的 mutt 命令,因为我不想发送邮件;)
我通过以编程方式创建数组 ("args") 伪造了 java 命令行。
使您的 StreamGobbler 静态化以便将其作为一个文件。
所有这些都不应该改变您的测试用例。真正不同的是执行 shell 而不是 /bin/echo
的 rt.exec 调用示例运行:
Execing echo "test" | grep -i "s"
ExitValue: 0
OUTPUT>test