我正在HP-UX计算机上从控制台运行java应用程序。在其中,我生成一些报告,压缩它们,然后通过电子邮件发送它们。除了电子邮件,一切正常。
我正在使用邮件二进制文件从命令行发送邮件。由于它是HP-UX,它与标准的GNU sendmail有点不同。
这是我用来发送邮件的代码:
public static void EmailReports(String[] recipients, String reportArchive, String subject){
SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy");
String today = dateFormat.format(new Date());
File tempEmailFile;
BufferedWriter emailWriter;
try {
tempEmailFile = File.createTempFile("report_email_" + today, "msg");
emailWriter = new BufferedWriter(new FileWriter(tempEmailFile));
} catch (IOException e) {
e.printStackTrace();
System.out.println("Failed to send email. Could not create temporary file.");
return;
}
try {
emailWriter.write("SUBJECT: " + subject + "\n");
emailWriter.write("FROM: " + FROM + "\n");
emailWriter.write(BODY + "\n");
emailWriter.close();
} catch (IOException e) {
e.printStackTrace();
System.out.println("Failed to send email. Could not write to temporary file.");
}
//read the archive in
try {
FileInputStream archiveIS = new FileInputStream(new File(reportArchive));
OutputStream archiveEncoder = MimeUtility.encode(new FileOutputStream(tempEmailFile, true), "uuencode", Zipper.getArchiveName(reportArchive));
//read archive
byte[] buffer = new byte[archiveIS.available()]; //these should never be more than a megabyte or two, so storing it in memory is no big deal.
archiveIS.read(buffer);
//encode archive
archiveEncoder.write(buffer);
//close both
archiveIS.close();
archiveEncoder.close();
} catch (FileNotFoundException e) {
System.out.println("Failed to send email. Could not find archive to email.");
e.printStackTrace();
} catch (MessagingException e) {
System.out.println("Failed to send email. Could not encode archive.");
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
System.out.println("Failed to send email. Could not encode archive.");
}
System.out.println("Sending '" + subject + "' email.");
try {
Process p = Runtime.getRuntime().exec("mail me@example.com < " + tempEmailFile.getAbsolutePath());
System.out.println("mail me@example.com < " + tempEmailFile.getAbsolutePath());
StringBuffer buffer = new StringBuffer();
while(p.getErrorStream().available() > 0){
buffer.append((char) p.getErrorStream().read());
}
System.out.println("STDERR: " + buffer.toString());
buffer = new StringBuffer();
while(p.getInputStream().available() > 0){
buffer.append((char) p.getInputStream().read());
}
System.out.println("STDOUT: " + buffer.toString());
} catch (IOException e) {
e.printStackTrace();
System.out.println("Failed to send email. Could not get access to the shell.");
}
}
当我运行程序并发送电子邮件时,我收到一封空白电子邮件,没有主题,没有正文,没有附件,而且来自HP-UX盒子中的user @ hostname,而不是来自指定的电子邮件FROM
。
但是,当我运行它运行的同一行时(请参阅我在调用exec后打印出的命令),我会从正确的用户那里收到包含主题,正文和附件的正确电子邮件。
STDOUT和STDERR都是空的。这几乎就像我发送邮件一个空白文件,但是当我打电话给exec之前打印文件时,它就在那里。
这里发生了什么?
编辑:尝试:
使用Ksh:
try {
String cmd = "mail me@example.com.com < " + tempEmailFile.getAbsolutePath();
Runtime.getRuntime().exec(new String[] {"/usr/bin/ksh", cmd});
} catch (IOException e) {
e.printStackTrace();
System.out.println("Failed to send email. Could not get access to the shell.");
}
使用STDIN:
try {
System.out.println("mail me@example.com < " + tempEmailFile.getAbsolutePath());
Process p = Runtime.getRuntime().exec("mail me@example.com ");
FileInputStream inFile = new FileInputStream(tempEmailFile);
byte[] byteBuffer = new byte[inFile.available()];
inFile.read(byteBuffer);
p.getOutputStream().write(byteBuffer);
inFile.close();
p.getOutputStream().close();
StringBuffer buffer = new StringBuffer();
while(p.getErrorStream().available() > 0){
buffer.append((char) p.getErrorStream().read());
}
System.out.println("STDERR: " + buffer.toString());
buffer = new StringBuffer();
while(p.getInputStream().available() > 0){
buffer.append((char) p.getInputStream().read());
}
System.out.println("STDOUT: " + buffer.toString());
} catch (IOException e) {
e.printStackTrace();
System.out.println("Failed to send email. Could not get access to the shell.");
}
答案 0 :(得分:2)
我强烈怀疑问题是重定向。这通常是由shell处理的 - 这里没有shell。
要么你需要正常执行流程,然后获取流程的标准输入流并从Java,或(可能更简单)运行{{1} (或者其他什么)让shell进行重定向。
答案 1 :(得分:2)
尝试执行{ "ksh", "-c", "mail me@example.com < " + etc }
。 -c
选项告诉shell专门将下一个参数解析为具有可能重定向的shell命令,依此类推。如果没有-c
,ksh会使用启发式方法来决定如何处理命令行,并且可能没有按照您希望的方式运行命令。
答案 2 :(得分:1)
分为两行,只是为了获得更好的可读性:
String cmd = "mail me@example.com < " + tempEmailFile.getAbsolutePath () ;
Process p = Runtime.getRuntime().exec (cmd);
这将查找名为"mail me@example.com < " + tempEmailFile.getAbsolutePath ()
的程序。它不会重定向 - 为此你必须自己阅读该过程的输出。
更进一步,它不会查找路径,因此您可能必须指定整个路径/ usr / bin / mail或其他任何内容。
你必须拆分命令和参数;改为使用字符串数组:(“/ path / to / prg”,“param1”,“param2”,“foo = bar”);
如果您将程序称为程序,则可以使用重定向,例如
String cmd = "/usr/bin/mail me@example.com < " + tempEmailFile.getAbsolutePath () ;
String cmdarr = new String [] {"/bin/bash", "-c", cmd};
Process p = Runtime.getRuntime().exec (cmdarr);
它比自己从Java调用文件重定向更短,更简单,但是你失去了对不同错误做出反应的能力。