Here is the way to go:
Runtime rt = Runtime.getRuntime();
String[] commands = {"system.exe", "-get t"};
Process proc = rt.exec(commands);
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(proc.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(proc.getErrorStream()));
// Read the output from the command
System.out.println("Here is the standard output of the command:\n");
String s = null;
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
// Read any errors from the attempted command
System.out.println("Here is the standard error of the command (if any):\n");
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
Read the Javadoc for more details here. ProcessBuilder would be a good choice to use.
Here is the way to go:
Runtime rt = Runtime.getRuntime();
String[] commands = {"system.exe", "-get t"};
Process proc = rt.exec(commands);
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(proc.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(proc.getErrorStream()));
// Read the output from the command
System.out.println("Here is the standard output of the command:\n");
String s = null;
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
// Read any errors from the attempted command
System.out.println("Here is the standard error of the command (if any):\n");
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
Read the Javadoc for more details here. ProcessBuilder would be a good choice to use.
A quicker way is this:
public static String execCmd(String cmd) throws java.io.IOException {
java.util.Scanner s = new java.util.Scanner(Runtime.getRuntime().exec(cmd).getInputStream()).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
Which is basically a condensed version of this:
public static String execCmd(String cmd) throws java.io.IOException {
Process proc = Runtime.getRuntime().exec(cmd);
java.io.InputStream is = proc.getInputStream();
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
String val = "";
if (s.hasNext()) {
val = s.next();
}
else {
val = "";
}
return val;
}
I know this question is old but I am posting this answer because I think this may be quicker.
Edit (For Java 7 and above)
Need to close Streams and Scanners. Using AutoCloseable for neat code:
public static String execCmd(String cmd) {
String result = null;
try (InputStream inputStream = Runtime.getRuntime().exec(cmd).getInputStream();
Scanner s = new Scanner(inputStream).useDelimiter("\\A")) {
result = s.hasNext() ? s.next() : null;
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
You need to the OutputStream (InputStream) of your Process (and you should use a ProcessBuilder)... like so
public static void main(String[] args) {
String filename = args[1].substring(0, args[1].length() - 5);
String cmd1 = "javac " + args[1];
String cmd2 = "java " + filename;
try {
// Use a ProcessBuilder
ProcessBuilder pb = new ProcessBuilder(cmd1);
Process p = pb.start();
InputStream is = p.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
int r = p.waitFor(); // Let the process finish.
if (r == 0) { // No error
// run cmd2.
}
} catch (Exception e) {
e.printStackTrace();
}
}
A general example to get the return from a command would be:
Process p = null;
try {
p = p = r.exec(cmd2);
p.getOutputStream().close(); // close stdin of child
InputStream processStdOutput = p.getInputStream();
Reader r = new InputStreamReader(processStdOutput);
BufferedReader br = new BufferedReader(r);
String line;
while ((line = br.readLine()) != null) {
//System.out.println(line); // the output is here
}
p.waitFor();
}
catch (InterruptedException e) {
...
}
catch (IOException e){
...
}
finally{
if (p != null)
p.destroy();
}
This is not Java question. Basically what you doing is running Java (Java Main Process A) and from it starting another process (Windows CMD B). This is fine and you can get input/output streams of this process (B) in Java(A). However this process (B) starts another process (again Windows CMD C) with its own standard input/output. This process has nothing common with processes A&B and uses Windows' standard Input/Output streams. So, there are no connections between A and C. I'm not sure but I think there are some ways to run Windows CMD with different or not standard IO. Maybe something like this will work:
cmd <tty >tty
but there is no tty in Windows. Pragmatically you can do this as described here - Creating a Child Process with Redirected Input and Output but that would not work for regular CMD.
Nevertheless it became even more problematic when you start your own process from the editorTemp.exe (process D). D has even more disconnection with process A. And all for what? What don't you simply start process D directly from A and have full control on the IO streams and process itself? Here is good example how to do so.
Your java thread is working independently of CMD call. The java code is beating the STDOUT pipe before anything is written.
If you call Process.waitFor(), it will wait until the CMD call is done. The STDOUT should be in the buffer, and then you can read it.
You can use the following code for this
import java.io.*;
public class doscmd
{
public static void main(String args[])
{
try
{
Process p=Runtime.getRuntime().exec("cmd /c dir");
p.waitFor();
BufferedReader reader=new BufferedReader(
new InputStreamReader(p.getInputStream())
);
String line;
while((line = reader.readLine()) != null)
{
System.out.println(line);
}
}
catch(IOException e1) {e1.printStackTrace();}
catch(InterruptedException e2) {e2.printStackTrace();}
System.out.println("Done");
}
}
You can use Runtime exec in java to execute dos commands from java code.
Based on Senthil's answer here:
Process p = Runtime.getRuntime().exec("cmd /C ver");
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()),8*1024);
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
// read the output from the command
String s = null;
System.out.println("Here is the standard output of the command:\n");
while ((s = stdInput.readLine()) != null)
System.out.println(s.replace("[","").replace("]",""));
Output = Microsoft Windows Version 6.1.7600
This full Java program example runs the command 'dir' (directory listing) on the command line and pulls the result into a String and prints it on the console.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class X {
public static void main(String[] args) {
try{
String command = "dir";
String s = get_commandline_results(command);
System.out.println(s);
}
catch(Exception e){
e.printStackTrace();
}
System.out.println("done");
}
public static String get_commandline_results(String cmd)
throws IOException, InterruptedException, IllegalCommandException{
//Do not remove the authorizedCommand method. Be prepared
//to lose your hard drive if you have not white-listed the
//commands that can run.
if (!authorizedCommand(cmd))
throw new IllegalCommandException();
String result = "";
final Process p = Runtime.getRuntime().
exec(String.format("cmd /c %s", cmd));
final ProcessResultReader stderr = new ProcessResultReader(
p.getErrorStream(), "STDERR");
final ProcessResultReader stdout = new ProcessResultReader(
p.getInputStream(), "STDOUT");
stderr.start();
stdout.start();
final int exitValue = p.waitFor();
if (exitValue == 0){
result = stdout.toString();
}
else{
result = stderr.toString();
}
return result;
}
public static boolean authorizedCommand(String cmd){
//Do not allow any command to be run except for the ones
//that we have pre-approved here. This lessens the
//likelihood that fat fingers will wreck your computer.
if (cmd.equals("dir"))
return true;
//add the commands you want to authorize here.
return false;
}
}
class ProcessResultReader extends Thread{
final InputStream is;
final String type;
final StringBuilder sb;
ProcessResultReader(final InputStream is, String type){
this.is = is;
this.type = type;
this.sb = new StringBuilder();
}
public void run()
{
try{
final InputStreamReader isr = new InputStreamReader(is);
final BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null)
{
this.sb.append(line).append("\n");
}
}
catch (final IOException ioe)
{
System.err.println(ioe.getMessage());
throw new RuntimeException(ioe);
}
}
@Override
public String toString()
{
return this.sb.toString();
}
}
class IllegalCommandException extends Exception{
private static final long serialVersionUID = 1L;
public IllegalCommandException(){ }
}
On Windows, this is the result I get
Directory of D:\projects\eric\eclipseworkspace\testing2
07/05/2012 01:06 PM <DIR> .
07/05/2012 01:06 PM <DIR> ..
06/05/2012 11:11 AM 301 .classpath
06/05/2012 11:11 AM 384 .project
06/05/2012 11:11 AM <DIR> .settings
07/05/2012 01:42 PM <DIR> bin
06/05/2012 11:11 AM <DIR> src
07/05/2012 01:06 PM 2,285 usernames.txt
3 File(s) 2,970 bytes
5 Dir(s) 45,884,035,072 bytes free
done
First you need a non-blocking way to read from Standard.out and Standard.err
private class ProcessResultReader extends Thread
{
final InputStream is;
final String type;
final StringBuilder sb;
ProcessResultReader(@Nonnull final InputStream is, @Nonnull String type)
{
this.is = is;
this.type = type;
this.sb = new StringBuilder();
}
public void run()
{
try
{
final InputStreamReader isr = new InputStreamReader(is);
final BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null)
{
this.sb.append(line).append("\n");
}
}
catch (final IOException ioe)
{
System.err.println(ioe.getMessage());
throw new RuntimeException(ioe);
}
}
@Override
public String toString()
{
return this.sb.toString();
}
}
Then you need to tie this class into the respective InputStream and OutputStreamobjects.
try
{
final Process p = Runtime.getRuntime().exec(String.format("cmd /c %s", query));
final ProcessResultReader stderr = new ProcessResultReader(p.getErrorStream(), "STDERR");
final ProcessResultReader stdout = new ProcessResultReader(p.getInputStream(), "STDOUT");
stderr.start();
stdout.start();
final int exitValue = p.waitFor();
if (exitValue == 0)
{
System.out.print(stdout.toString());
}
else
{
System.err.print(stderr.toString());
}
}
catch (final IOException e)
{
throw new RuntimeException(e);
}
catch (final InterruptedException e)
{
throw new RuntimeException(e);
}
This is pretty much the boiler plate I use when I need to Runtime.exec() anything in Java.
A more advanced way would be to use FutureTask and Callable or at least Runnable rather than directly extending Thread which isn't the best practice.
NOTE:
The @Nonnull annotations are in the JSR305 library. If you are using Maven, and you are using Maven aren't you, just add this dependency to your pom.xml.
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>1.3.9</version>
</dependency>
Use getErrorStream().
BufferedReader in = new BufferedReader(new InputStreamReader(pr.getErrorStream()));
EDIT:
You can use ProcessBuilder (and also read the documentation)
ProcessBuilder ps=new ProcessBuilder("java.exe","-version");
//From the DOC: Initially, this property is false, meaning that the
//standard output and error output of a subprocess are sent to two
//separate streams
ps.redirectErrorStream(true);
Process pr = ps.start();
BufferedReader in = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
pr.waitFor();
System.out.println("ok!");
in.close();
System.exit(0);
Note that we're reading the process output line by line into our StringBuilder. Due to the try-with-resources statement we don't need to close the stream manually. The ProcessBuilder class let's us submit the program name and the number of arguments to its constructor.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class ProcessOutputExample
{
public static void main(String[] arguments) throws IOException,
InterruptedException
{
System.out.println(getProcessOutput());
}
public static String getProcessOutput() throws IOException, InterruptedException
{
ProcessBuilder processBuilder = new ProcessBuilder("java",
"-version");
processBuilder.redirectErrorStream(true);
Process process = processBuilder.start();
StringBuilder processOutput = new StringBuilder();
try (BufferedReader processOutputReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));)
{
String readLine;
while ((readLine = processOutputReader.readLine()) != null)
{
processOutput.append(readLine + System.lineSeparator());
}
process.waitFor();
}
return processOutput.toString().trim();
}
}
Prints:
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)
As one of the commenters mentioned this might result in quite complex setups you are running into. It is most likely in your case that an error happens in java and you just do not see the output since error messages are written to the STDERR stream instead of STDOUT.
So there are two options (1) you take the code you already have and also try to read from the process' ErrorStream.
Bufferedreader error = new BufferedReader(new InputStreamReader(p.getErrorStream());
Or if you do not care whether or not the process you were starting was writing to STDERR or to STDOUT you can also use a ProcessBuilder and just set it up to redirect the error stream.
ProcessBuilder pb = new ProcessBuilder("java", "helloworld");
pb.redirectErrorStream(true); // this redirects STDERR to STDOUT
Process p = pb.start();
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
output += (line + '\n');
}
input.close();
For the sake of simplicity I omitted all the boilerplate code and exception handling in the above. But I think you will get the idea.
Why are you using the Process builder and executing the same. Why not use JavaCompiler interface. See the documentation it is really well written.
Instead of
while ((line = input.readLine()) != null) {
output += (line + '\n');
}
To output the results to the command line immediately just print within the while loop
while ((line = input.readLine()) != null) {
System.out.println(line);
output += (line + '\n');
}
You can print out continuously with:
while ((line = input.readLine()) != null) {
System.out.println(line);
output += (line + '\n');
}
(The following is still useful for future viewers, but is not an applicable answer to the question.)
Simply insert a process.waitFor() before reading from the output stream. This command waits until a process dies before continuing. You then don't have to read line by line, either. You can simply dump the buffer all at once.
Either this, or you can find a string which only occurs on the last line (e.g. Minimum in Windows) and change the while condition to:
while((line == input.readline()).indexOf("Minimum") == -1)