从Java执行终端命令

4

我知道有很多关于这个问题的帖子,但是没有一个适用于我。这是我想做的:

从我的Java代码中编译和运行一个文件。在Windows上可以工作,但我也想让它在UNIX上工作。这里是代码:

if(os.equals("win")){
        //For Windows
        try {
            Runtime.getRuntime().exec(
                            "cmd /c start cmd.exe /K "
                            + "\"cd " + path + "&& "
                            + "javac " + name + ".java && "
                            + "echo ^>^>" + name + ".java " + "outputs: &&"
                            + "echo. &&"
                            + "java " + name + " && "
                            + "echo. &&"
                            + "pause && "
                            + "exit\"");
        } catch (IOException e) {
            System.out.println("Didn't work");
        }
    }else{
        try {
            //TODO make it work for UNIX
            Runtime.getRuntime().exec("");
        } catch (IOException e) {
            System.out.println("Didn't work");
        }
    }

问题是,在UNIX系统上,它的行为是“不可预测的”。 例如:
Runtime.getRuntime().exec("open image.png");

打开这张图片但是

Runtime.getRuntime().exec("javac Test.java");
Runtime.getRuntime().exec("echo 'hello'");

它什么也不做,没有信息。

我非常感谢任何输入。

更新------------------------------------------------------------

似乎与Windows CMD相比,终端需要一个InputStreamReader来显示exec中发生了什么。我在另一个线程中找到了这段代码,现在至少可以从exec终端获得一些输出。

   String line;
   Process p = Runtime.getRuntime().exec( "echo HelloWorld2" );

   BufferedReader in = new BufferedReader(
           new InputStreamReader(p.getInputStream()) );
   while ((line = in.readLine()) != null) {
     System.out.println(line);
   }
   in.close();

但事情仍然是神秘的,因为执行

Process p = Runtime.getRuntime().exec("javac Test.java");

可以工作并生成一个Test.class文件。但是

Process p = Runtime.getRuntime().exec("javac Test.java && java Test");

却没做任何事情。(没有任何错误消息。终端“执行”但是没有结果。)在终端中手动输入此命令会按预期构建并运行。我错过了什么?


它的哪个方面不起作用?你得到了什么输出?你期望得到什么? - Reinstate Monica -- notmaynard
“won't work”是什么意思?你能与我们分享异常堆栈跟踪吗? - AlexR
Runtime.exec() 返回一个 Process 对象,该对象具有可用的 stdout 和 stderr 流 - 读取这些流应该可以给您任何操作系统生成的错误消息。 - BarrySW19
好的。有趣的是,在Windows上,所有错误消息都直接显示在cmd窗口中。 - Haeri
PS:那个踩票怎么回事?哪一部分显示没有研究努力;不清楚或无用? - Haeri
显示剩余2条评论
1个回答

2
我没有可供使用的Linux系统,但我非常确定上述第二条命令试图编译名为"Test.java"、"&&"、"java"和"Test"的Java文件。换句话说,Runtime.exec()方法会字面地处理参数,而不是应用shell解释。
你可以尝试使用以下命令:
Process p = Runtime.getRuntime().exec(
    new String[] { "sh",  "-c", "javac Test.java && java Test" });

差不多了!事情开始运作了!我现在可以串联我的命令。但还有一件事。Test.java 有一个 System.out.println("worked!"); 但它没有显示在任何地方...(在 Windows 中,即使是刚编译和执行的文件,每个 I/O 都会显示在同一个 cmd 窗口中。)这里编译后的文件(Test.class)的 I/O 不会显示出来。 - Haeri
输出应该进入通过exec()调用返回的Process对象获取的stdout流。 - BarrySW19

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