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

将带空格的字符串传递给Java中的execute命令以执行bash脚本,java,bash,unix,process,runtime.exec,Java,Bash,Unix,Process,Runtime.exec,如何将带空格的字符串传递给Java中的execute命令以执行bash脚本 我试图使用unixmail命令使用脚本生成和发送电子邮件,但它忽略了消息字符串周围的引号: #!/bin/bash ###################################################### # # Params: # 1) Email recipient # 2) Subject line (in quotes) # 3) Message (in quotes) # # Return

如何将带空格的字符串传递给Java中的execute命令以执行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)
where

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();

我现在成功地获得了要记录的输出所示的正确参数,但我从未收到过电子邮件。如果我通过终端手动调用脚本,我确实收到了电子邮件,但不要使用
Runtime.exec()
,始终使用
ProcessBuilder
,它允许您以数组或字符串集合的形式传递参数

为了更好地处理错误,您应该真正使用和日志框架,如


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

不要使用
Runtime.exec()
,始终使用
ProcessBuilder
,它允许您以数组或字符串集合的形式传递参数

为了更好地处理错误,您应该真正使用和日志框架,如


如果您不确定如何使用ProcessBuilder和进程之间的I/O,您应该更好地使用它来解决许多常见问题,如正确处理三个I/O流。

正如其他人所提到的,使用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"

正如其他人所提到的,使用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"

这实际上是通过改变:

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


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

,这实际上是通过更改:

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


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

将命令分解成
字符串[]
应该可以工作,然后将其更新为使用
ProcessBuilder
。但是为了更快地获得更好的帮助,请发布一个。没有回答您的问题,但是您是否考虑过使用?@greg Kopff我们已经和我们的技术负责人决定我们需要很多权限才能获得批准,这只是一种变通方法,因为我们只需要一个简单的通知请尝试
“\”我的主题行\
“\”这是测试消息!!\”
。这将向终端发送一个实际的引号,将字符串分组,将命令拆分为
字符串[]
应该可以工作,然后将其更新为使用
ProcessBuilder
。但是为了更快地获得更好的帮助,请发布一个。没有回答您的问题,但是您是否考虑过使用?@greg Kopff我们已经和我们的技术负责人决定我们需要很多权限才能获得批准,这只是一种变通方法,因为我们只需要一个简单的通知请尝试
“\”我的主题行\
“\”这是测试消息!!\”“
。这将向终端发送一个实际的引号,对您的字符串进行分组我已将其更改为按照您的建议使用ProcessBuilder,它现在已成功获取正确的参数,但是,我从未实际收到邮件,但id我自己在终端上执行脚本,有什么建议吗?您还需要关闭stdin,阅读stdout和stderr并调用
waitFor()
,以确保进程可以正确终止。很抱歉,我不完全理解,你能给我举个例子吗(即使是一个链接也很好)我已经按照你的建议将其改为使用ProcessBuilder,它现在成功地获得了正确的参数,但是,我从来没有收到过邮件,但我自己在终端上执行脚本,有什么建议吗?你还需要关闭stdin,阅读stdout和stderr,并调用
waitFor()
,以确保进程可以正确终止。很抱歉,我不完全理解,你能给我举个例子吗(即使是一个链接也很好)不幸的是,我使用的是Java 6,而您似乎使用的是Java 7,而且当我手动调用脚本时,引号似乎不会引起任何问题,但我会以任何方式尝试。在这种情况下,您可能希望将
process.getInputStream()
传递给一个不断读取和丢弃(或日志)的新线程字节。不幸的是,我使用的是Java 6,而您似乎使用的是Java 7,而且当我手动调用脚本时,引号似乎不会引起任何问题,但我会以任何方式尝试。在这种情况下,您可能希望将
process.getInputStream()
传递给一个不断读取和丢弃(或记录)字节的新线程。