0

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

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

#!/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();

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

4

3 回答 3

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}但由于某种原因它不喜欢这样

于 2013-05-14T09:50:30.400 回答
1

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

为了更好地处理错误,您应该真正使用Java Mail API和像slf4j这样的日志框架。

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

于 2013-05-13T12:44:41.890 回答
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"
于 2013-05-13T14:17:38.893 回答