简体   繁体   English

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

[英]Pass a string with spaces to an execute command in Java to execute a bash script

How do I pass a string with spaces to an execute command in Java to execute a bash script? 如何将带有空格的字符串传递给Java中的execute命令以执行bash脚本?

I'm trying to use a script to generate and send a email using the unix mail command but it ignores the quotes surrounding the message string: 我正在尝试使用脚本使用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

and this is how I'm calling it in java : 这就是我在java中调用它的方式:

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

The problem is it takes "My as the subject argument and Test as the message argument and ignores the rest. 问题在于它将"My作为主题参数,将"My Test作为消息参数,而忽略其余参数。

I have tried using single quotes, exec(command, args) where 我尝试使用单引号exec(command, args)在哪里

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

but still has the same result. 但仍然有相同的结果。

I have searched here and online but most people seem to suggests what I have tried and while it worked for them, it did not for me. 我在这里和在线上进行了搜索,但是大多数人似乎都在暗示我尝试过的方法,尽管它对他们有用,但对我却没有。

Update 更新

On the Advice of a number of comments/Answers I have changed from using the exec to 根据一些意见/答案的建议,我已从使用exec更改为

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

I now successfull get the correct Arguments as shown by the output to log BUT I never recieve the email. 现在,我成功获取了输出显示的正确参数,但没有收到电子邮件记录。 If I call the script via the terminal manually I do recieve the email 如果我通过终端手动调用脚本,我会收到电子邮件

This was actually solved by changing: 这实际上是通过更改来解决的:

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

To: 至:

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

I had also Perviously tried passing an array of strings args = {this.scriptName, mailTo, subject, message} but for some reason it did not like this 我也曾尝试过传递一个字符串数组args = {this.scriptName, mailTo, subject, message}但由于某种原因它不喜欢这样

Don't use Runtime.exec() , always use ProcessBuilder which allows you to pass arguments as an array or a collection of Strings. 不要使用Runtime.exec() ,请始终使用ProcessBuilder ,它允许您将参数作为数组或字符串集合进行传递。

And for better error handling, you should really use the Java Mail API and a logging framework like slf4j . 为了更好地处理错误,您应该真正使用Java Mail API和类似slf4j的日志记录框架。

If you're unsure how to use ProcessBuilder and I/O between processes, you should better use Commons Exec which solves many of the common problems like handing the three I/O streams correctly. 如果不确定如何在进程之间使用ProcessBuilder和I / O,则最好使用Commons Exec ,它可以解决许多常见问题,例如正确处理三个I / O流。

As others have mentioned, use ProcessBuilder. 正如其他人提到的那样,请使用ProcessBuilder。 However, just starting the process isn't enough; 但是,仅仅启动该过程是不够的。 you must consume its output, and you may or may not want to wait for it to complete. 您必须使用它的输出,并且您可能想要也可能不想等待它完成。 For example: 例如:

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

It isn't just the process invocation that needs to quote spaces. 不仅仅是需要引用空格的过程调用。 I'm pretty sure you need quotes in your script: 我很确定您在脚本中需要使用引号:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM