在Java中运行命令行

140

有没有一种方法可以在Java应用程序中运行这个命令行?

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

我可以使用命令运行它,但是我无法在Java中运行它。


我已经尝试过了,Runtime rt = Runtime.getRuntime();Process proc = rt.exec("ping localhost"); - Ataman
1
你想从另一个虚拟机中启动虚拟机吗? - chance
你可以试试我的小型图书馆Jaxec - undefined
8个回答

214

当我尝试将其输出到控制台时,它只输出类似于这样的内容:java.lang.ProcessImpl@6ecec5288。这种情况正常吗? - Ataman
8
请使用 pr.getInputStream() 方法。以下是详细示例:http://www.linglom.com/2007/06/06/how-to-run-command-line-or-execute-external-application-from-java/ - kol
6
检查进程返回值是很有用的。您可以使用pr.waitFor()获得该值。代码如下:int retVal = pr.waitFor()。如果返回值不为0,则可以中止/清理操作。 - Apache
1
pr.exitValuepr.waitFor()之间有实际/有意义的区别吗?更新:我认为如果进程尚未完成,exitValue将抛出异常,而waitFor...您知道。 - Don Cheadle
3
没有比“Runtime rt = Runtime.getRuntime();”更Java的东西了。 - Andrea Bori
这个答案有问题。除非你同时读取stderr和stdout,否则被调用的应用程序将会阻塞。如果只有少量输出被写入,你可能能够逃过这个问题,但一旦缓冲区超出限制,一切都会停止。 - Brett Sutton

60

你也可以像这样查看输出:

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

别忘了,如果你正在运行Windows命令,你需要在命令前面加上cmd /c

编辑:为了额外加分,你也可以使用ProcessBuilder将输入传递给程序:

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

这将运行Windows命令choice /C YN /M "如果你很酷,请按Y"并响应Y。因此,输出将是:

Press Y if you're cool [Y,N]?Y

5
你还可以使用p.getErrorStream来了解命令出错的原因! - jakebeal
1
@Craigo:你的“cmd /c”语句有任何参考资料吗?谢谢。 - Campa
2
实际上,我认为你只需要使用“cmd /c”,如果你想要运行一个Windows命令,比如“copy”。对于造成的困扰,我深表歉意。 - Craigo
1
这对我来说没有打印整个输出。执行 "ls" 每次都会打印不同数量的目录内容。这对我最好的解决方法是:http://alvinalexander.com/java/edu/pj/pj010016 - stuart

22

为避免当被调用的进程在标准输出和/或错误流上输出大量数据时被阻塞,您需要使用Craigo提供的解决方案。还请注意,ProcessBuilder优于Runtime.getRuntime().exec()。原因有几个:它更好地对参数进行了分词,并且还负责处理错误的标准输出(也可以在这里查看)。

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

// Watch the process
watch(process);

我使用了一个新的函数"watch"来在一个新的线程中收集这些数据。当被调用的进程结束时,该线程将在调用进程中完成。

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

1
谢谢你指出来,我实际上很困惑,因为我没有stderr。 - Melwin Kieffer

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

最短的代码总是我最喜欢的。 - Zhang Buzz

8
import java.io.*;

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

如果你遇到任何进一步的问题,请考虑以下内容,但我猜上述内容对你来说应该已经够用了: Runtime.exec() 的问题

4

那么呢?

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

 }

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

3

您尝试过在Runtime类中使用exec命令吗?


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

Runtime - Java Documentation


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接