[英]How to run commands you can run on terminal in Java
所以伙計們,我想執行一個可以在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
有ProcessBuilder
,我一直使用Runtime.getRuntime().exec("cmd");
它返回一個Process ,您可以獲取它的輸入和輸出流
即使您使用ProcessBuilder
,您仍應有權訪問Process.get<Input/Output/Error>Stream()
您需要通過打開流程的輸入流來讀取流程的輸出:
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)
將錯誤流自動添加到輸入流中。 當然,您無法再區分輸入來自哪個流,但這使閱讀更加容易。 如果您不讀取輸入或錯誤流,並且進程的緩沖區已滿,則進程將暫停,直到緩沖區中再次有足夠的空間。
您也可以添加
builder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
在start方法之前,它將輸出重定向到控制台。
//"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();
現有的答案為您提供了有關如何解決代碼問題的信息,但沒有給出代碼無法正常工作的原因。
在外殼上執行程序時,在執行程序之前,外殼會進行大量處理。 您的命令行
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
由外殼啟動時,從不知道這種重定向,也根本不了解>>
和目標文件名。
有了這些信息,就可以使用其他任何答案中的代碼示例。 我不會將它們復制到我的網站上以進行適當的歸屬。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.