DevilCode
DevilCode

Reputation: 1100

Java getRuntime Exec

Am calling a p = Runtime.getRuntime().exec(command) on Java 1.8. The command calls a bash script as follows:

#!/bin/bash
args=("$@")
cat /home/user/Downloads/bigtext.txt | grep ${args[0]}

The above bash script works fine when called with the command line. When called within my Java application using exec() I get no CAT output back. it does not seem to get past p.waitFor(); Where am I going wrong?

If I run a command directly such as "ls -alF" every thing works as expected.

$ java -version java version "1.8.0_31" Java(TM) SE Runtime Environment (build 1.8.0_31-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.31-b07, mixed mode)


String tmp = "/home/user/search "+input;        
System.out.println(tmp); //  /home/user/search sometextarg
String woa = executeCommand(tmp);


private String executeCommand(String command) {     
        StringBuilder output = new StringBuilder();
                BufferedReader reader = null;
        Process p;
        try {
            p = Runtime.getRuntime().exec(command);
            p.waitFor();

                        reader = new BufferedReader(new InputStreamReader(p.getInputStream()));

            String line = "";

            while ((line = reader.readLine())!= null) {
                output.append(line + "\n");
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return output.toString();
    }

Upvotes: 1

Views: 966

Answers (1)

that other guy
that other guy

Reputation: 123410

Your Java process and your script are deadlocked waiting on each other: you are waiting for the process to exit, the process is waiting for you to read the output.

It happens to work for ls -alF and other commands with small outputs because they all fit in the pipe's buffer (64kib on my system).

Just move the p.waitFor() below the while loop, and you'll have more luck:

private String executeCommand(String command) {     
    StringBuilder output = new StringBuilder();
            BufferedReader reader = null;
    Process p;
    try {
        p = Runtime.getRuntime().exec(command);
        reader = new BufferedReader(new InputStreamReader(p.getInputStream()));

        String line = "";
        while ((line = reader.readLine())!= null) {
            output.append(line + "\n");
        }
        p.waitFor();

    } catch (Exception e) {
        e.printStackTrace();
    }
    return output.toString();
}

If you additionally want this to work correctly with values containing spaces and certain other characters, you have to:

  1. Quote "${args[0]}" in your script.
  2. Rewrite your executeCommand to use Runtime.exec(String[]) instead of Runtime.exec(String).

Upvotes: 3

Related Questions