Running command in linux environment fails

Issue

I am trying to execute a command via Runtime.getRuntime().exec().
When i run the following command in my linux bash it works fine.

Command: bash -c "npm -v"

But when i try to run it with Java it fails with the following error:

-v": -c: line 0: unexpected EOF while looking for matching `"'
-v": -c: line 1: syntax error: unexpected end of file

Reproducible example:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;

public class RunACommandTest
{

   public static void main(String[] args)
   {
      try
      {
         Process exec = Runtime.getRuntime().exec("bash -c \"npm -v\"");

         new BufferedReader(new InputStreamReader(exec.getInputStream(), StandardCharsets.UTF_8))
               .lines()
               .forEachOrdered(line -> System.out.println("IN " + line));

         new BufferedReader(new InputStreamReader(exec.getErrorStream(), StandardCharsets.UTF_8))
               .lines()
               .forEachOrdered(line -> System.out.println("ERR " + line));

      }
      catch(IOException e)
      {
         throw new RuntimeException(e);
      }
   }

}

I have also tried to use single quotes instead of double quotes.

Solution

Unfortunately the now deprecated Runtime.exec(String) breaks up this command incorrectly as 4 argument command { "bash", "-c", "\"npm", "-v\"" }. Separating the parameter list as 3 argument command { "bash", "-c", "npm -v" } will avoid this problem.

It is easier to use ProcessBuilder which is used internally by Runtime.exec:

ProcessBuilder pb = new ProcessBuilder("bash","-c", "npm -v");
Process exec = pb.start();

Note that you must consume stdout + stderr in separate threads. What you have above may work, but it may freeze for other processes or conditions. You can avoid by redirect to file, or redirect error to stdout with:

pb.redirectErrorStream(true);

Answered By – DuncG

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published