I\'m trying to run commands straight through the CMD on Windows (Terminal on Linux). I have the following code. It\'s acting very strangely. First, when run the program does
You can execute commands without actually hard coding cmd.exe into the code.
public static void main(String[] args) {
//cmd = the command youw ill be using
String cmd = "ipconfig";
Runtime r = Runtime.getRuntime();
Process p;
try {
p = r.exec(cmd);
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println(inputLine);
}
}
catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
I found this code on the net years ago. I cant remember where. It's pretty old so there might be something better out there now.
private void executeCommand(String cmd) {
try {
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(cmd);
// any error message?
StreamHandler errorGobbler = new StreamHandler(proc.getErrorStream(), "ERR");
// any output?
StreamHandler outputGobbler = new StreamHandler(proc.getInputStream(), "OUT");
// kick them off
errorGobbler.start();
outputGobbler.start();
// any error???
int exitVal = proc.waitFor();
System.out.println("ExitValue: " + exitVal);
} catch (Exception e) {
e.printStackTrace();
}
}
And the class:
import java.util.*;
import java.io.*;
public class StreamHandler extends Thread {
InputStream is;
String type;
OutputStream os;
StringBuffer output;
StreamHandler(InputStream is, String type) {
this(is, type, null);
}
StreamHandler(InputStream is, String type, OutputStream redirect) {
this.is = is;
this.type = type;
this.os = redirect;
output = new StringBuffer(100);
}
public void run() {
try {
PrintWriter pw = null;
if (os != null)
pw = new PrintWriter(os);
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line=null;
while ( (line = br.readLine()) != null) {
if (pw != null)
pw.println(line);
System.out.println(type + ">" + line);
}
if (pw != null)
pw.flush();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
Typically cmd
or terminal
are responsible for setting up standard io for the programs they execute, so I don't think you can just communicate with them via input/output stream. In case of Linux it's actually the shell run inside terminal that executes commands, not terminal itself. Windows probably does some funky things, too.
There could be a couple of things going on. One is that arguments are not getting passed correctly the way you are executing the process. The other, like @zacheusz mentioned, is that output may be coming out from the error stream instead of the input stream.
ProcessBuilder helps with both these things, allowing easy construction of a list of commands and the ability to merge input and error stream. I recommend trying using it:
Process p = null;
try {
List<String> cmd = new LinkedList<String>();
cmd.add("executable");
cmd.add("-arg1");
cmd.add("value1");
cmd.add("-arg2");
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.redirectErrorStream(true);
p = pb.start();
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
while (input.ready()) {
String line = input.readLine();
System.out.println("From process: "+line);
}
input.close();
} catch (IOException e) {
this.logMessage("IOException caught: "+e.getMessage());
e.printStackTrace();
}
You need to do this work in a Thread. For example to log the standard output:
Process process = Runtime.getRuntime().exec(command);
LogStreamReader lsr = new LogStreamReader(process.getInputStream());
Thread thread = new Thread(lsr, "LogStreamReader");
thread.start();
public class LogStreamReader implements Runnable {
private BufferedReader reader;
public LoggingStreamReader(InputStream is) {
this.reader = new BufferedReader(new InputStreamReader(is));
}
public void run() {
try {
String line = reader.readLine();
while (line != null) {
System.out.println(line);
line = reader.readLine();
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Then you need a second thread for input handling. And you might want to deal with stderr just like stdout.
cmd tries to run a command prompt ,
to run the command properly you need the following command line
cmd.exe -c ipconfig.exe
the -c means run the command on the rest of the command line