Because the Exec Binding simply uses the string as is in Runtime.getRuntime().exec spaces cannot be used in an argument (see below).
Use this workaround if you need them: File /toArgs.java (edit for example with sudo vim /toArgs.java)
import java.io.*;
public class toArgs {
public static void main(String[] args) throws java.io.IOException {
StringBuilder cmnd = new StringBuilder();
for (int i = 0; i < args.length; i++) {
cmnd.append(args[i]);
if (i != args.length - 1) {
cmnd.append(" ");
}
}
//System.out.println(cmnd.toString());
String line;
Process p = Runtime.getRuntime().exec(new String[] {"bash", "-c", cmnd.toString()});
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
}
}
For windows users: replace “bash” with “cmd” and “-c” with “/c”
The compile using sudo javac /toArgs.java In your command now prepend java -cp / toArgs
Explanation
When the exec function receives a string, it is parsed using the Tokenizer class. This class always splits at spaces, completely disregarding quotes.
For example the command wget --post-data "some data" http://example.com gets parsed into wget--post-data"somedata"http://example.com (notice the quotes and the split argument). This is unwanted behavior, as quotes indicate one argument.
If parsed by bash, the command would result in wget--post-datasome datahttp://example.com (some data is one argument, no quotes). This workaround accomplishes that by reconstructing the original string and then passing it to bash using the -c option.
With each block being one element in the arguments array.
Problems
Not really a problem, but this spawns two additional programs compared to a fix in the source (first the workaround and the bash).
I will open an issue on github.
Thanks, I did not know that. Sadly, if you take a look at the source, this is achieved by openHAB. The Exec binding does not provide this functionality, so this doesn’t help my case. Interesting anyways
I think the parser in the binding and in the action need some improvements, so that they recognise things enclosed in single/double quotes as a single argument. Surely there’s already a code / library / someone out there that has solved this issue.
I’ll second the request for the PR. This is probably the root of a lot of user’s problems with Exec and executeCommandLine.
In many programming languages, the solve the issue by flexing around the issue. Instead of supplying a string to be parsed, you pass in an array of arguments. Then it doesn’t matter if there are spaces and whatnot.
Since you’re a foundation member, could you please kindly do the PR? I am not familiar with this (if PR means pull request, I’ve never done that before)…