2011-07-18 17 views
0

我試圖通過Windows上的CMD(Linux上的終端)直接運行命令。我有以下代碼。它的表現非常奇怪。首先,運行程序時不打印任何東西。其次,當調試並逐步完成時,程序將打印默認的CMD文本和輸入行。最後,我似乎無法寫入CMD,因此它會執行命令。這是我的代碼。我猜這可能是一個線程問題,但我不熟悉運行時。使用CMD作爲過程

Runtime r = Runtime.getRuntime(); 
    try { 
     Process p = r.exec("cmd"); 
     InputStream iStream = p.getInputStream(); 
     BufferedReader sReader = new BufferedReader(new InputStreamReader(iStream)); 
     while(sReader.ready()) { 
      System.out.print((char)sReader.read()); 
     } 

     OutputStream oStream = p.getOutputStream(); 
     BufferedWriter sWriter = new BufferedWriter(new OutputStreamWriter(oStream)); 
     sWriter.write("mkdir test"); 
     sWriter.newLine(); 

     while(sReader.ready()) { 
      System.out.print((char)sReader.read()); 
     } 
    } catch(Exception e) { 
     e.printStackTrace(); 
    } 

而且我的輸出調試,並通過加大時,(沒有輸出顯示當其運行)

Microsoft Windows XP [Version 5.1.2600] 
(C) Copyright 1985-2001 Microsoft Corp. 

D:\workspaces\Maven\Command Line> 
+1

是否有一個原因,您使用'cmd'而不是直接運行每個命令? – unholysampler

+3

@unholysampler:如果這個目的是爲了在Windows上運行,它需要這樣做(或者'cmd/c mkdir test'作爲一行)。 'mkdir'內置於Windows命令處理器;它不是一個單獨的可執行文件。當然,爲什麼您需要使用'cmd' [而不是標準庫]運行'mkdir'命令(http://download.oracle.com/javase/6/docs/api/java/io/File.html #mkdir())超出了我。 – ig0774

+0

我沒有使用mkdir,我只是用它作爲一個簡單的例子。實際的CMD命令很長且很難看,動態值 – Spidy

回答

1

可能有一些事情正在進行。一個是參數不能正確地通過你執行過程的方式。另一個,如@zacheusz提到的,輸出可能來自錯誤流而不是輸入流。

ProcessBuilder幫助完成這些事情,允許輕鬆構建命令列表以及合併輸入和錯誤流的能力。我建議使用它嘗試:

Process p = null; 
try { 
    List<String> cmd = new LinkedList<String>(); 
    cmd.add("executable"); 
    cmd.add("-arg1"); 
    cmd.add("value1"); 
    cmd.add("-arg2"); 
    ProcessBuilder pb = new ProcessBuilder(cmd); 
    pb.redirectErrorStream(true); 
    p = pb.start(); 
    BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream())); 
    while (input.ready()) { 
     String line = input.readLine(); 
     System.out.println("From process: "+line); 
    } 
    input.close(); 
} catch (IOException e) { 
    this.logMessage("IOException caught: "+e.getMessage()); 
    e.printStackTrace(); 
} 
1

你需要做這項工作的主題。例如要記錄標準輸出:

Process process = Runtime.getRuntime().exec(command); 
LogStreamReader lsr = new LogStreamReader(process.getInputStream()); 
Thread thread = new Thread(lsr, "LogStreamReader"); 
thread.start(); 


public class LogStreamReader implements Runnable { 

    private BufferedReader reader; 

    public LoggingStreamReader(InputStream is) { 
     this.reader = new BufferedReader(new InputStreamReader(is)); 
    } 

    public void run() { 
     try { 
      String line = reader.readLine(); 
      while (line != null) { 
       System.out.println(line); 
       line = reader.readLine(); 
      } 
      reader.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

然後,您需要第二個線程進行輸入處理。你可能想要像標準輸出一樣處理stderr。

0

通常cmdterminal負責爲他們執行的程序設置標準io,所以我不認爲你只能通過輸入/輸出流與他們溝通。在Linux的情況下,它實際上是在執行命令的終端內運行的shell,而不是終端本身。 Windows也可能做一些有趣的事情。

1

我幾年前在網上發現了這個代碼。我不記得在哪裏。這很舊,所以現在可能會有更好的東西。

private void executeCommand(String cmd) { 
     try { 
      Runtime rt = Runtime.getRuntime(); 

      Process proc = rt.exec(cmd); 

      // any error message? 
      StreamHandler errorGobbler = new StreamHandler(proc.getErrorStream(), "ERR"); 

      // any output? 
      StreamHandler outputGobbler = new StreamHandler(proc.getInputStream(), "OUT"); 

      // kick them off 
      errorGobbler.start(); 
      outputGobbler.start(); 

      // any error??? 
      int exitVal = proc.waitFor(); 
      System.out.println("ExitValue: " + exitVal); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 


    } 

和類:

import java.util.*; 
import java.io.*; 

public class StreamHandler extends Thread { 
    InputStream is; 
    String type; 
    OutputStream os; 

    StringBuffer output; 

    StreamHandler(InputStream is, String type) { 
     this(is, type, null); 
    } 

    StreamHandler(InputStream is, String type, OutputStream redirect) { 

     this.is = is; 
     this.type = type; 
     this.os = redirect; 
     output = new StringBuffer(100); 
    } 

    public void run() { 
     try { 
      PrintWriter pw = null; 
      if (os != null) 
       pw = new PrintWriter(os); 

      InputStreamReader isr = new InputStreamReader(is); 
      BufferedReader br = new BufferedReader(isr); 
      String line=null; 
      while ((line = br.readLine()) != null) { 
       if (pw != null) 
        pw.println(line); 
       System.out.println(type + ">" + line); 
      } 
      if (pw != null) 
       pw.flush(); 
     } catch (IOException ioe) { 
      ioe.printStackTrace(); 
     } 
    } 
} 
-1

您可以執行命令,而無需實際硬編碼的cmd.exe到代碼。

public static void main(String[] args) { 

     //cmd = the command youw ill be using    
    String cmd = "ipconfig";  
    Runtime r = Runtime.getRuntime();  
    Process p; 
    try {  
     p = r.exec(cmd); 

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


catch (IOException ex) {  
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); 
      } 
     } 
+0

沒理由? :(這似乎是一個合理的答案 – sealz

-1

CMD嘗試運行命令提示符下,

正常運行的命令,你需要下面的命令行

的cmd.exe -c IPCONFIG.EXE

-c表示在命令行的其餘部分運行該命令