所以我想要执行一个可以在我的Java程序中的cmd上执行的命令。在做了一些研究后,我以为我找到了一种方法来做到这一点。但是,我的代码不起作用。
我的代码是
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 :(得分:0)
虽然有ProcessBuilder
,但我总是使用Runtime.getRuntime().exec("cmd");
它返回Process,您可以获得
的输入和输出流即使您使用ProcessBuilder
,您仍然可以访问Process.get<Input/Output/Error>Stream()
答案 1 :(得分:0)
您需要通过打开流程中的输入流来读取流程的输出:
try (BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream())) {
System.out.println(reader.readLine()); // process the output stream somehow
}
另外,您可能会在Java 8中读取错误流(p.getErrorStream()
)(我经常在单独的流中完成),您可以使用redirectErrorStream(true)
上的ProcessBuilder
自动添加输入流的错误流。当然,你不能再区分输入来自哪个流,但它使阅读更容易。如果您没有读取输入或错误流并且进程的缓冲区已满,则进程会暂停,直到缓冲区中有足够的空间。
答案 2 :(得分:0)
您也可以添加
builder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
在start方法之前将输出重定向到控制台。
答案 3 :(得分: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();
答案 4 :(得分: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
命令知道重定向其输出的>>
参数 - 这里是shell发挥作用的地方:>>
运算符是指令到shell ,告诉它如何处理来自进程的stdout的输出。进程ag
,当由shell启动时,从来不知道这个重定向,并且根本没有关于>>
和目标文件名的线索。
使用此信息,只需使用来自任何其他答案的代码示例。我不会将它们复制到我的正确归属中。