1

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

asked Dec 31, 2019 at 23:11
10
  • could share the code that runs the command ? to see how you pass the string Commented Dec 31, 2019 at 23:18
  • So, this would be a little messy to continue down the path you've started, a possibly better solution would be to use ProcessBuilder which may reduce the need to quote any of the parameters at all Commented Dec 31, 2019 at 23:18
  • @MadProgrammer As I said, I have no control over this... I need to do it in one string :( Commented Dec 31, 2019 at 23:20
  • The shell may support quoting. You could use something like bash -c 'wget ... "..." ...'. Commented Dec 31, 2019 at 23:27
  • And why can't you use ProcessBuilder? You call getRuntime by yourself. What frameworks prevents that? Commented Dec 31, 2019 at 23:30

1 Answer 1

2

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:

    1. 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.xml
      
    2. Make the script executable

    3. Run it:

       Runtime.getRuntime().exec("/tmp/abc.sh");
      
answered Dec 31, 2019 at 23:51
Sign up to request clarification or add additional context in comments.

1 Comment

Sadly I have to send different data. I also don't have control over the exec parameters, so no chance of the first two options. Seems I can only try to write a script that generates the data without having to use spaces... Thanks!

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.