【问题标题】:Get output of cmd command from java code从 java 代码中获取 cmd 命令的输出
【发布时间】:2013-12-27 15:58:49
【问题描述】:

我有一个程序可以从我的代码中成功执行 cmd 命令,但我希望能够从 cmd 命令中获取输出。我该怎么做?

到目前为止,我的代码是:

Second.java:

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

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

我可以通过检查 Second.class 来检查第一个命令是否成功运行,但是如果这个类产生了一些错误,我怎么能看到那个错误呢?

【问题讨论】:

    标签: java windows cmd exec runtime.exec


    【解决方案1】:

    您需要 Process 的 OutputStream (InputStream)(并且您应该使用 ProcessBuilder)...像这样

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

    【讨论】:

    • 我希望能够在执行第二个命令时打印错误,当我现在测试它时,它只在编译和运行成功时打印输出,但是当我从 Second. java 并运行 Main.java 它只是给了我一个空输出而不是说缺少分号,我应该添加什么来让它也打印错误?
    • 这是真的吗?对于可以在 PHP 中写成 $output = `command`; 的东西,Java 需要 20 行代码、一个进程构建器、一个缓冲阅读器,还有什么?这种过度抽象甚至不是故事的全部——这段代码泄露了资源,因为流永远不会关闭......
    • @TheOperator 什么真的是真的吗?在bash 你可以写output=$(command);不同的语言是不同的(例如,Java 不是 脚本 语言)。另外,上例中的资源在main 退出时关闭。
    • @ElliottFrisch Java 是否是脚本语言无关紧要。将整个功能(调用系统命令并获取其输出)包装到一个方法中是很容易的,而无需强迫用户处理进程、缓冲读取器、循环、IO 异常和所有样板文件。关于资源,操作系统负责释放已关闭应用程序的文件句柄,而不是 Java。此类代码通常用于更复杂的应用程序,而不仅仅是 main() 方法——如果它运行的时间更长,正确地释放系统资源很重要。
    • @TheOperator 您如何获得 C 或 C++ 程序的输出?用户必须处理进程(popen(3))、(缓冲)读取器(fscanf)、循环、IO 异常,甚至更多样板。使用 Scala,您可以创建自定义 DSL 来包装此功能,就像 脚本 语言一样;但是这个 Java。
    【解决方案2】:

    从命令中获取返回的一般示例是:

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

    【讨论】:

      【解决方案3】:

      看这里:Extracting a process's exit code in the case of ThreadInterrupted

      你需要得到返回码……你必须等待它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-01-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-18
        • 1970-01-01
        • 1970-01-01
        • 2012-01-05
        相关资源
        最近更新 更多