Reputation: 1100
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
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:
"${args[0]}"
in your script. executeCommand
to use Runtime.exec(String[])
instead of Runtime.exec(String)
.Upvotes: 3