Reputation: 12680
How do I pass a string with spaces to an execute command in Java to execute a bash script?
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:
#!/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 :
Process proc = Runtime.getRuntime().exec(scriptName+" [email protected] \"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.
I have tried using single quotes, exec(command, args)
where
args = {"[email protected]","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.
On the Advice of a number of comments/Answers I have changed from using the exec
to
ProcessBuilder pb = new ProcessBuilder(scriptName, "[email protected]","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
Upvotes: 0
Views: 3757
Reputation: 12680
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
Upvotes: 2
Reputation: 328556
Don't use Runtime.exec()
, always use ProcessBuilder
which allows you to pass arguments as an array or a collection of Strings.
And for better error handling, you should really use the Java Mail API and a logging framework like 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.
Upvotes: 1
Reputation: 44293
As others have mentioned, use 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, "[email protected]","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"
Upvotes: 1