5

I have a program where I was able to successfully execute cmd commands from my code, but I want to be able to get the output from the cmd command. How can I do that?

So far my code is:

Second.java:

public class Second {
    public static void main(String[] args) {
        System.out.println("Hello world from Second.java");
    }
}

and Main.java

public class Main {
    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;

        Runtime r = Runtime.getRuntime();
        Process p = r.exec(cmd1); // i can verify this by being able to see Second.class and running it successfully
        p = r.exec(cmd2); // i need to see this output to see if 

        System.out.println("Done");
    }
}

I can check the first command is working successfully by checking for Second.class, but what if this class generated some error, how will I be able to see that error?

3 Answers 3

9

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();
  }
}
Sign up to request clarification or add additional context in comments.

6 Comments

I want to be able to print the errors when executing the second command, when I was testing it now, it only printed output when compilation and run was successful, but when I removed a semicolon from Second.java and run Main.java it just gave me an empty output instead of saying there was a missing semicolon, what should I add to allow it to print errors too?
Is that really true? For something you can write as $output = `command`; in PHP, Java needs 20 lines of code, a process builder, a buffered reader and what-not? This over-abstraction is not even the full story -- this code leaks resources, because the streams are never closed...
@TheOperator Is what really true? In bash you can write output=$(command); different languages are different (for example, Java isn't a scripting language). Also, the resources are closed in the example above when main exits.
@ElliottFrisch Whether Java is a script language or not is not relevant. It would have been easily possible to wrap this entire functionality (calling a system command and getting its output) into a method, without forcing the user to deal with processes, buffered readers, loops, IO exceptions and all that boilerplate. Regarding resources, the OS takes care of releasing file handles of closed applications, not Java. Such code is typically used in more complex applications, not just a main() method -- and if it's running for a longer time, deallocating system resources properly is important.
@TheOperator And how would you get the output of a program in C or C++? The user has to deal with processes (popen(3)), (buffered) readers (fscanf), loops, IO exceptions and even more boilerplate. With Scala, you could create a custom DSL to wrap this functionality like a scripting language; but this is Java.
|
4

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();
    }

Comments

1

look here: Extracting a process's exit code in the case of ThreadInterrupted

You need to get the return code... you must wait for it.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.