将带空格的字符串传递给Java中的执行命令以执行bash脚本

时间:2013-05-13 12:37:17

标签: java bash unix process runtime.exec

如何将带空格的字符串传递给Java中的执行命令以执行bash脚本?

我正在尝试使用脚本生成并使用unix mail命令发送电子邮件,但它忽略了消息字符串周围的引号:

#!/bin/bash

######################################################
#
# Params:
# 1) Email recipient
# 2) Subject line (in quotes)
# 3) Message (in quotes)
#
# Returns:
# 0 if success, else non-zero
#####################################################

MAIL_TO=$1
SUBJECT_LINE=$2
MESSAGE=$3

echo "Mail To= ${MAIL_TO}" >> /logs/terminalLog.txt
echo "Subject= ${SUBJECT_LINE}" >> /logs/terminalLog.txt
echo "Message= ${MESSAGE}" >> /logs/terminalLog.txt
echo "" >> /logs/terminalLog.txt

echo "$MESSAGE" | mail -s "$SUBJECT_LINE" $MAIL_TO >> /logs/terminalLog.txt

这就是我在java中调用它的方式:

Process proc = Runtime.getRuntime().exec(scriptName+" me@someplace.com \"My Test Subject Line\" \"This is the test message!!\"");

问题是它需要"My作为主题参数而Test作为消息参数并忽略其余参数。

我尝试使用单引号,exec(command, args)其中

args = {"me@someplace.com","My Test Subject Line","This is the test message!!" } 

但仍然有相同的结果。

我在这里和网上搜索过,但是大多数人似乎都在暗示我尝试了什么,虽然它适用于他们,但它并不适合我。

更新

关于一些评论/答案的建议我已经从使用exec更改为

ProcessBuilder pb = new ProcessBuilder(scriptName, "me@somePlace.com","My Test Subject Line", "This is the test message!!");
pb.start();

我现在成功获取正确的参数,如输出所示,但我从未收到过电子邮件。如果我通过终端手动调用脚本,我会收到电子邮件

3 个答案:

答案 0 :(得分:2)

这实际上是通过改变来解决的:

String command =    scriptName+" "+mailTo+" "+"\""+subject+"\""+" "+"\"" + message + "\"";
Runtime rtime = Runtime.getRuntime();
Process proc = rtime.exec(command.toString());
int retCode = proc.waitFor();           

要:

 Runtime rtime = Runtime.getRuntime();
 Process proc = rtime.exec(new String[] {this.scriptName, mailTo, subject, message} );
 int retCode = proc.waitFor();

我还试过传递一个字符串数组args = {this.scriptName, mailTo, subject, message}但是由于某种原因它不喜欢这个

答案 1 :(得分:1)

不要使用Runtime.exec(),总是使用ProcessBuilder,它允许您将参数作为数组或字符串集合传递。

为了更好地处理错误,您应该使用Java Mail APIslf4j等日志框架。

如果您不确定如何在进程之间使用ProcessBuilder和I / O,则最好使用Commons Exec来解决许多常见问题,例如正确处理三个I / O流。< / p>

答案 2 :(得分:1)

正如其他人所提到的,使用ProcessBuilder。但是,刚开始这个过程是不够的;你必须消耗它的输出,你可能想也可能不想等它完成。例如:

ProcessBuilder pb = new ProcessBuilder(scriptName, "me@somePlace.com","My Test Subject Line", "This is the test message!!");
pb.redirectOutput(ProcessBuilder.Redirect.INHERIT);
pb.start();

int returnCode = pb.waitFor();
if (returnCode != 0) {
    throw new IOException("Command failed with code " + returnCode);
}

不仅需要引用空格的进程调用。我很确定你的脚本中需要引号:

SUBJECT_LINE="$2"
MESSAGE="$3"