![](/img/trans.png)
[英]Why will shell script not execute from Java Runtime.exec but will from command line?
[英]Java Runtime.exec() not sending emails as from the command line
我正在創建一個java應用程序,我想添加的一個功能是將生成的電子郵件發送給用戶。 我在Macbook上設置了郵件,我可以從命令行發送電子郵件。 我在調用runtime.exec()時發送電子郵件時遇到問題。 任何人都知道為什么它不會執行和發送電子郵件?
Runtime runtime = Runtime.getRuntime();
try {
runtime.exec("echo This is the body | mail -s Subject -F myemail@gmail.com");
}
catch ( Exception e ) {
// TODO Auto-generated catch block
e.printStackTrace();
}
我沒有得到任何錯誤,一切都編譯得很好。 我只是沒有收到任何電子郵件。 如果有人能夠幫助,將非常感謝謝謝。
Runtime.exec(String)
不會通過將其粘貼到UNIX shell並運行它來執行整個字符串。 這是因為它是一個巨大的安全漏洞。
想象一下你這樣做了:
runtime.exec("Hello "+name+" | mail ...");
然后我可以設置name
; rm -rf /*; echo
; rm -rf /*; echo
; rm -rf /*; echo
或&& cat /etc/passwd
,或其他一些shell注入代碼。
因此, Java正在將您的命令分解為多個部分 :
更確切地說,命令字符串使用由調用new StringTokenizer(命令)創建的StringTokenizer分解為標記,而不進一步修改字符類別。 然后,由標記化器生成的標記以相同的順序放置在新的字符串數組cmdarray中。
最終,您將單獨運行echo
命令,其參數如|
和mail
。 echo
命令只會將這些輸出打印到您不收集的標准輸出。 它永遠不會調用mail
命令。
由於涉及安全風險,您不應使用mail
命令從Java發送郵件。 您應該使用JavaMail包,它提供了一個安全方便的API來發送郵件。 UNIX mail
命令通過連接到端口25上本地計算機上運行的sendmail
守護程序來工作,JavaMail也可以這樣做。
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMessage.RecipientType;
public class SendMail {
public static sendMail(String from, String to, String subject, String body)
throws MessagingException
{
final Properties p = new Properties();
p.put("mail.smtp.host", "localhost");
final Message msg = new MimeMessage(Session.getDefaultInstance(p));
msg.setFrom(new InternetAddress(from));
msg.addRecipient(RecipientType.TO, new InternetAddress(to));
msg.setSubject(subject);
msg.setText(body);
Transport.send(msg);
}
}
你為什么不使用JavaMail ?
用法示例:
private boolean sendMail(String host, String port, String user, String password, List<String> toList, String htmlBody, String subject) {
Properties props = System.getProperties();
props.put("mail.smtp.user", user);
props.put("mail.smtp.password", password);
props.put("mail.smtp.host", host);
props.put("mail.smtp.port", port);
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.EnableSSL.enable", "true");
Session session = Session.getInstance(props, null);
MimeMessage message = new MimeMessage(session);
try {
message.setFrom(new InternetAddress(user));
// To get the array of addresses
for (String to : toList) {
message.addRecipient(Message.RecipientType.TO,
new InternetAddress(to));
}
message.setSubject(subject);
message.setContent(htmlBody, "text/html");
Transport transport = session.getTransport("smtp");
try {
transport.connect(host, user, password);
transport.sendMessage(message, message.getAllRecipients());
} finally {
transport.close();
}
} catch (Exception e) {
return false;
}
return true;
}
因為你沒有產生shell和| 是一個shell功能。 一個有效的例子:
創建一個shell腳本並將命令數組傳遞給exec()。
class Test {
public static void main(String[] args) {
try {
Runtime runtime = Runtime.getRuntime();
String[] cmd = { "sh", "send.sh", "This is the body", "Subject", "myemail@gmail.com"};
runtime.exec(cmd);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Shell腳本:
echo $1 | mail -s $2 -F $3
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.