2011-04-19 1226 views
98

我正在使用运行时从我的Java程序运行命令提示符命令。但是我不知道如何获得命令返回的输出。java runtime.getruntime()从执行命令行程序获取输出

这里是我的代码:

Runtime rt = Runtime.getRuntime(); 

String[] commands = {"system.exe" , "-send" , argument}; 

Process proc = rt.exec(commands); 

我想这样做System.out.print(proc);但没有返回任何东西。该命令的执行应该返回两个以分号分隔的数字,我怎样才能得到这个变量打印出来?

这是我现在使用的代码:

String[] commands = {"system.exe","-get t"}; 

Process proc = rt.exec(commands); 

InputStream stdin = proc.getInputStream(); 
InputStreamReader isr = new InputStreamReader(stdin); 
BufferedReader br = new BufferedReader(isr); 

String line = null; 
System.out.println("<OUTPUT>"); 

while ((line = br.readLine()) != null) 
    System.out.println(line); 

System.out.println("</OUTPUT>"); 
int exitVal = proc.waitFor(); 
System.out.println("Process exitValue: " + exitVal); 

但我没有得到任何东西作为我的输出,但是当我运行该命令自己正常工作。

+23

1没有比该行多个Java - 运行时RT =调用Runtime.getRuntime(); – 2014-11-12 02:58:46

+8

...除运行时Runtime runtime = Runtime.getRuntime(); :D – 2017-02-19 13:48:32

回答

157

这里是要走的路:

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

更好地阅读的Javadoc了解更多详情hereProcessBuilder会是不错的选择使用

+0

你是否知道如何一次获得多个命令的输出,比如“pwd && ls” – 2015-01-13 04:18:01

+4

@AlbertChen'pwd && ls'不只是执行一个文件,当你在shell中这样做的时候它会执行'/ bin/pwd'和'/ bin/ls'可执行文件。如果你想在java中做类似的事情,你需要做一些像'{“/ bin/bash”,“ - c”,“pwd && ls”}'的东西。你可能不再有这个问题了,但其他人可能会这样认为我可以回答它。 – 735Tesla 2015-01-25 22:05:26

+0

我认为阅读这两个流必须同时发生,因为如果像你的情况那样,stdStream的输出将填充缓冲区,你将无法读取错误流。 – Li3ro 2017-10-16 07:38:57

10

除了使用ProcessBuilder的建议塞特希,请务必仔细阅读并实施When Runtime.exec() won't所有建议。

+0

我使用该网站上的代码,但我没有得到任何输出,请检查我的更新代码。 – user541597 2011-04-19 04:35:47

+0

该片段似乎并没有使用标准错误流(正如链接文章中推荐的那样)。它也没有像现在推荐的那样使用'ProcessBuilder'两次。使用'ProcessBuilder',可以合并输出和错误流,以便更容易同时使用。 – 2011-04-19 05:42:43

43

更快的方法是这样的:

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

这基本上是这样一个浓缩版本:

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

我知道这个问题是旧的,但因为我认为这可能我张贴这个答案快点。

+0

感谢您的好回答。为什么“\\ A”是分隔符? – Gottfried 2014-03-06 17:53:26

+0

我不完全记得当我最初写这个时我的逻辑是什么。我一直在使用这个解决方案一段时间,但我认为这是因为正则表达式中的'\ A'意味着字符串开始,我不得不逃脱斜线。 – 735Tesla 2014-03-06 23:43:48

+2

“\ A”是钟形文字。 “^”是正则表达式中字符串的开始,“$”是正则表达式中字符串的结尾。这是你期望看不到的角色。根据Java文档,默认的分隔符是空格,所以这样做可能会吐出命令的完整结果。 – 2015-05-12 20:32:22

0

改编自以前的答案

public static String execCmdSync(String cmd, CmdExecResult callback) throws java.io.IOException, InterruptedException { 
    RLog.i(TAG, "Running command:", cmd); 

    Runtime rt = Runtime.getRuntime(); 
    Process proc = rt.exec(cmd); 

    //String[] commands = {"system.exe","-get t"}; 

    BufferedReader stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream())); 
    BufferedReader stdError = new BufferedReader(new InputStreamReader(proc.getErrorStream())); 

    StringBuffer stdout = new StringBuffer(); 
    StringBuffer errout = new StringBuffer(); 

    // 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); 
     stdout.append(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); 
     errout.append(s); 
    } 

    if (callback == null) { 
     return stdInput.toString(); 
    } 

    int exitVal = proc.waitFor(); 
    callback.onComplete(exitVal == 0, exitVal, errout.toString(), stdout.toString(), cmd); 

    return stdInput.toString(); 
} 

public interface CmdExecResult{ 
    void onComplete(boolean success, int exitVal, String error, String output, String originalCmd); 
} 
-1

要读的运行时的InputStream:

Runtime rt = Runtime.getRuntime(); 
String[] commands = {"system.exe","-send",argument}; 
Process proc = rt.exec(commands); 
BufferedReader br = new BufferedReader(
    new InputStreamReader(proc.getInputStream())); 
String line; 
while ((line = br.readLine()) != null) 
    System.out.println(line); 
} 

您可能还需要读取错误流(proc.getErrorStream())如果过程是印刷错误输出。如果使用ProcessBuilder,则可以将错误流重定向到输入流。

8

@Senthil和@Arend答案(https://stackoverflow.com/a/5711150/2268559)提到了ProcessBuilder。下面是使用的ProcessBuilder与指定环境变量和工作文件夹该命令的例子:

ProcessBuilder pb = new ProcessBuilder("ls", "-a", "-l"); 

    Map<String, String> env = pb.environment(); 
    // If you want clean environment, call env.clear() first 
    // env.clear() 
    env.put("VAR1", "myValue"); 
    env.remove("OTHERVAR"); 
    env.put("VAR2", env.get("VAR1") + "suffix"); 

    File workingFolder = new File("/home/user"); 
    pb.directory(workingFolder); 

    Process proc = pb.start(); 

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