Running Command Line in Java [duplicate]
Asked Answered
T

8

141

Is there a way to run this command line within a Java application?

java -jar map.jar time.rel test.txt debug

I can run it with command but I couldn't do it within Java.

Tripod answered 13/12, 2011 at 21:35 Comment(3)
I have tried, Runtime rt = Runtime.getRuntime();Process proc = rt.exec("ping localhost");Tripod
Do you want to launch a VM from within another VM?Beady
You can try my small library JaxecRuwenzori
J
214
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec("java -jar map.jar time.rel test.txt debug");

http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html

Janessa answered 13/12, 2011 at 21:38 Comment(6)
is it normal that when i try to output it to console it only outputs something like this: java.lang.ProcessImpl@6ecec5288Tripod
Use pr.getInputStream(). Here is a detailed example: linglom.com/2007/06/06/…Janessa
It's useful to check what the process returns with. You can get that with pr.waitFor(). So it looks like this: int retVal = pr.waitFor(). So if it's not 0, you can abort / clean up.Oehsen
Is there a practical/meaningful difference between pr.exitValue and pr.waitFor()? Update: I think exitValue will throw an exception if the process has not finished where as waitFor... you knowTwoply
nothing it's more java than "Runtime rt = Runtime.getRuntime();"Veilleux
This answer is problematic. The called app will block unless you read BOTH stderr and stdout. You will get away with it if only a small amount of output is written but once the buffer is exceeded everything stops.Esbjerg
L
61

You can also watch the output like this:

final Process p = Runtime.getRuntime().exec("java -jar map.jar time.rel test.txt debug");

new Thread(new Runnable() {
    public void run() {
        BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
        String line = null;

        try {
            while ((line = input.readLine()) != null)
                System.out.println(line);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}).start();

p.waitFor();

And don't forget, if you are running a windows command, you need to put cmd /c in front of your command.

EDIT: And for bonus points, you can also use ProcessBuilder to pass input to a program:

String[] command = new String[] {
        "choice",
        "/C",
        "YN",
        "/M",
        "\"Press Y if you're cool\""
};
String inputLine = "Y";

ProcessBuilder pb = new ProcessBuilder(command);
pb.redirectErrorStream(true);
Process p = pb.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));

writer.write(inputLine);
writer.newLine();
writer.close();

String line;

while ((line = reader.readLine()) != null) {
    System.out.println(line);
}

This will run the windows command choice /C YN /M "Press Y if you're cool" and respond with a Y. So, the output will be:

Press Y if you're cool [Y,N]?Y
Lorettalorette answered 9/9, 2014 at 2:0 Comment(4)
You can also use p.getErrorStream to understand why your command is broken!Interstadial
@Craigo: any reference regarding your "cmd /c" statement? thxPastelist
Actually, I think you only need the "cmd /c", if you are wanting to run a windows command, like "copy". Apologies for the confusion.Lorettalorette
this doesn't print the whole output for me. executing "ls" prints different amounts of the directory contents each time. this works best for me: alvinalexander.com/java/edu/pj/pj010016Catwalk
I
22

To avoid the called process to be blocked if it outputs a lot of data on the standard output and/or error, you have to use the solution provided by Craigo. Note also that ProcessBuilder is better than Runtime.getRuntime().exec(). This is for a couple of reasons: it tokenizes better the arguments, and it also takes care of the error standard output (check also here).

ProcessBuilder builder = new ProcessBuilder("cmd", "arg1", ...);
builder.redirectErrorStream(true);
final Process process = builder.start();

// Watch the process
watch(process);

I use a new function "watch" to gather this data in a new thread. This thread will finish in the calling process when the called process ends.

private static void watch(final Process process) {
    new Thread() {
        public void run() {
            BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line = null; 
            try {
                while ((line = input.readLine()) != null) {
                    System.out.println(line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }.start();
}
Inadvertent answered 18/6, 2015 at 22:25 Comment(1)
Thank you for pointing that out, I was actually struggling because I had no stderr.Redheaded
T
8
Runtime.getRuntime().exec("java -jar map.jar time.rel test.txt debug");
Toxoplasmosis answered 13/12, 2011 at 21:39 Comment(1)
The shortest code is always my favorite.Hectoliter
O
8
import java.io.*;

Process p = Runtime.getRuntime().exec("java -jar map.jar time.rel test.txt debug");

Consider the following if you run into any further problems, but I'm guessing that the above will work for you:

Problems with Runtime.exec()

Oxalate answered 13/12, 2011 at 21:44 Comment(0)
C
4

what about

public class CmdExec {

public static Scanner s = null;


public static void main(String[] args) throws InterruptedException, IOException {
    s = new Scanner(System.in);
    System.out.print("$ ");
    String cmd = s.nextLine();
    final Process p = Runtime.getRuntime().exec(cmd);

    new Thread(new Runnable() {
        public void run() {
            BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String line = null; 

            try {
                while ((line = input.readLine()) != null) {
                    System.out.println(line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }).start();

    p.waitFor();
     }

 }
Cheeseburger answered 25/7, 2015 at 4:38 Comment(0)
H
3
Process p = Runtime.getRuntime().exec("java -jar map.jar time.rel test.txt debug");
Hoahoactzin answered 13/12, 2011 at 21:38 Comment(0)
B
3

Have you tried the exec command within the Runtime class?

Runtime.getRuntime().exec("java -jar map.jar time.rel test.txt debug")

Runtime - Java Documentation

Blastula answered 13/12, 2011 at 21:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.