2017-10-13 109 views
0

所以我想执行一个命令,你可以在我的Java程序的cmd上执行命令。在做了一些研究之后,我想我找到了一个办法来做到这一点。但是,我的代码不起作用。如何运行你可以在Java终端上运行的命令

我的代码是

import java.io.*; 

public class CmdTest { 
    public static void main(String[] args) throws Exception { 
     String[] command = {"ag","startTimes conf.js >> pro.txt"}; 
     ProcessBuilder builder = new ProcessBuilder(command); 
     builder.directory(new File("./test-java/")); 
     Process p = builder.start(); 
    } 
} 

程序执行,但不产生任何输出。我尝试使用其他命令,如“ls -a”,但仍然没有输出。

有人可以帮我调试这个或建议一个更好的方式做到这一点?谢谢

编辑1:我在Mac上执行此操作。如果这是必要的调试

编辑2:通常的LS和其他命令正在与你们提供的解决方案。然而,我想在Java程序中使用ag(the_silver_searcher)命令。当我尝试,我得到以下错误 -

Exception in thread "main" java.io.IOException: Cannot run program "ag startTimes conf.js >> pro.txt": error=2, No such file or directory 
+0

你是在Windows还是Linux环境中运行它? –

+0

@AustinA,我在Mac上运行这个 – Sid

回答

0

现有答案为您提供了有关如何解决代码问题的信息,但他们没有给出您的代码无法工作的原因。

当你在一个shell上执行一个程序时,在程序执行之前,shell会完成相当多的处理。你的命令行

String[] command = {"ag","startTimes conf.js >> pro.txt"}; 
    ProcessBuilder builder = new ProcessBuilder(command); 

假设命令ag参数startTimes conf.js >> pro.txt运行 - 很可能不是你想要做什么。让我们更进一步:如果你写了

String[] command = {"ag","startTimes", "conf.js", ">>", "pro.txt"}; 
    ProcessBuilder builder = new ProcessBuilder(command); 

这将假设ag命令知道的>>参数重定向输出 - 这里是其中壳发挥作用:该>>运算符是一个指令到外壳,告诉做什么与过程的stdout输出。当由shell启动时,ag进程永远不知道这个重定向,并且完全不知道>>和目标文件名。

有了这些信息,只需使用任何其他答案的代码示例。我不会将它们复制到我的正确归属中。

+0

非常感谢你,奥拉夫,你的投入真的帮助。我终于能够解决问题 – Sid

0

虽然有ProcessBuilder,我一直使用Runtime.getRuntime().exec("cmd");

Process Runtime.exec(String)

它返回一个Process,你可以得到的输入和输出流

即使您留在ProcessBuilder,您仍应该有权访问Process.get<Input/Output/Error>Stream()

+0

我得到错误 - “线程中的异常”main“java.io.IOException:无法运行程序”ag startTimes conf.js >> pro.txt“:error = 2,No这样的文件或目录“。你建议我做什么? – Sid

+0

@Sid尝试放入完整的文件路径,它可能从本地目录运行命令 – phflack

0

您需要通过从过程打开的输入流读取过程的输出:

try (BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream())) { 
    System.out.println(reader.readLine()); // process the output stream somehow 
} 

另外,你可能会在读取错误流(p.getErrorStream()),我经常都在一个单独的数据流进行,在Java 8中,您可以使用ProcessBuilder上的redirectErrorStream(true)自动将错误流添加到输入流。当然,你不能区分输入来自哪一个流,但它使阅读更容易。如果您未读取输入或错误流,并且进程的缓冲区已满,则进程会暂停,直到缓冲区中有足够空间。

+0

我得到错误 - “线程中的异常”main“java.io.IOException:无法运行程序”ag startTimes conf.js >> pro。 txt“:错误= 2,没有这样的文件或目录”。你建议我做什么? – Sid

0

也可以被重定向输出到控制台的启动方法前加

builder.redirectOutput(ProcessBuilder.Redirect.INHERIT); 

+0

嘿,本,当我使用像ls这样的命令时,你的解决方案就可以工作。但是当我使用ag命令时,出现错误 - 线程“main”异常java.io.IOException:无法运行程序“ag startTimes conf.js >> pro.txt”:error = 2,No such file或目录 – Sid

+0

我现在可以做什么? – Sid

+1

你在问一个新问题。接受提供给您的两种解决方案中的一种并且可能发布新的SO问题是公平的。 –

0
//"ls" command runs under the "sh" on linux(cmd.exe on windows), so first arg is "sh"  
//second arg "-c" tells "sh" which exact command should be executed 
//"ls" is actual command 
//"startTimes" as I understand is a file or directory, it is arg for "ls" command 
//"conf.js" is second arg for "ls" command 
new ProcessBuilder("sh", "-c", "ls", "startTimes", "conf.js") 
//set working dir for "sh" process" 
      .directory(new File("./test-java/")) 
//output will be written to "pro.txt" in working dir of "sh" process 
      .redirectOutput(new File("./test-java/pro.txt")) 
      .start(); 
+1

请回顾[我如何写一个好的答案](https://stackoverflow.com/help/how-to-answer)。不接受代码的答案是不鼓励的,因为他们没有解释他们如何解决问题中的问题。你应该更新你的答案,以解释这是什么以及如何解决问题。 – FluffyKitten