Due to working through a framework, I only have control over the command string of Runtime.getRuntime().exec(string), so no array.
Problem is, I need to pass some escaped arguments and it just doesn't seem to work.
Take this for example: wget -qO- --post-data "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Devices><Device><FLOWCTRL>2</FLOWCTRL></Device></Devices>" -- http://192.168.3.33/data/changes.xml. Works perfectly fine in the shell, but something is messed up since I don't get the proper response (most probably because the data isn't valid).
Edit: https://github.com/openhab/openhab-addons/blob/2.5.x/bundles/org.openhab.binding.exec/src/main/java/org/openhab/binding/exec/internal/handler/ExecHandler.java#L174 Link to code
1 Answer 1
As I said, I have no control over this... I need to do it in one string :(
There is no direct solution given that constraint. Period.
It is a plain fact that exec(String) does not understand any form of escaping or quoting. It splits the string into a command name and multiple arguments using whitespace characters as the argument separator. The behavior is hard-wired ... and documented.
The possible solutions are:
- Do the splitting yourself, and use
exec(String[]). Get a shell to do the splitting; e.g.
String cmd = "wget -qO- --post-data \"<?xml version=\\"1.0\\" ...." Runtime.getRuntime().exec("/bin/sh", "-c", cmd);Note that we are using
exec(String[])here too.Generate and run a shell script on the fly:
Write the following script to a temporary file (say "/tmp/abc.sh")
#!/bin/sh wget -qO- --post-data \ "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Devices><Device><FLOWCTRL>2</FLOWCTRL></Device></Devices>" \ -- http://192.168.3.33/data/changes.xmlMake the script executable
Run it:
Runtime.getRuntime().exec("/tmp/abc.sh");
ProcessBuilderwhich may reduce the need to quote any of the parameters at allbash -c 'wget ... "..." ...'.