0

I got stuck trying to run a compound shell command from a Groovy script. It was one of those commands where you separate with "&&" so that the 2nd command never runs if the 1st one fails. For whatever reason I couldn't get it to work. I was using:

println "custom-cmd -a https://someurl/path && other-cmd -f parameter".execute([], new File('/some/dir')).text

The shell kept misinterpreting the command throwing errors like "custom-cmd -f invalid option" It was like it was ignoring the "&&" in between. I tried using a semi-colon as well but was not lucky. I tried using straight Java APIs Runtime.getRuntime().exec() and splitting the command into an array. I tried wrapping the command in single quotes and giving it to '/bin/sh -c' but nothing works.

How do you run a compound shell command from Java? I know I've done this in the past but I cannot figure it out today.

tim_yates
  • 167,322
  • 27
  • 342
  • 338
Cliff
  • 10,586
  • 7
  • 61
  • 102
  • Perhaps you need to escape the &&. – Rob Kielty Dec 29 '15 at 10:11
  • 1
    Possible duplicate of [how to call shell commands from groovy correctly](http://stackoverflow.com/questions/12512919/how-to-call-shell-commands-from-groovy-correctly). you can not use "shellism" like && < | as commands. use `-c` and pass it as _one_ param (easiest done by string array, if the quoting gets tricky) – cfrick Dec 29 '15 at 10:28

2 Answers2

2

With groovy, the list form of execute should work:

def out = ['bash', '-c', "custom-cmd -a https://someurl/path && other-cmd -f parameter"].execute([], new File('/some/dir')).text

Of course you may want to use the consumeProcessOutput method on process, as if the output is too large, calling text may block

tim_yates
  • 167,322
  • 27
  • 342
  • 338
  • This works! Thank you! It was not working when I passed /bin/sh as the executable but bash seems to work. Also I did not know that List also supports the execute method! Nice! – Cliff Dec 29 '15 at 19:12
0

Try something like:

Runtime.getRuntime().exec("cmd /c \"start somefile.bat && start other.bat && cd C:\\test && test.exe\"");

Runtime.getRuntime().exec() can be used without splitting the commands into an array.

see https://stackoverflow.com/a/18867097/1410671

EDIT:

Have you tried using a ProcessBuilder? This seems to work on my OSX box:

public static void main(String[] args) throws IOException {
    ProcessBuilder builder = new ProcessBuilder( "/bin/sh", "-c", "echo '123' && ls" );

    Process p=null;
    try {
        p = builder.start();
    }
    catch (IOException e) {
        System.out.println(e);
    }


    Scanner s = new Scanner( p.getInputStream() );
    while (s.hasNext())
    {
        System.out.println( s.next() );
    }
    s.close();
}
Community
  • 1
  • 1
randal4
  • 590
  • 4
  • 16
  • As explained above, I already tried something like this. (I'm on OSX) I used /bin/sh -c 'cmd && othercmd' – Cliff Dec 29 '15 at 03:29
  • Also, I've tried both splitting and not splitting the cmd. Usually splitting on white space works better but not in this case. – Cliff Dec 29 '15 at 03:31