2013-04-18 79 views
1

我目前正在從事一個項目,其中客戶端從服務器接收shell/console命令,並且必須執行它們。如何執行一系列相關的控制檯命令?

如何讓Java從shell或命令提示符中運行這些命令?我希望能夠忽略平臺類型 - 而不必指定shell或命令提示符 - 但如果我不能,那就沒問題。

我必須能夠發送相關命令的序列,而不只是一個命令。這意味着shell/prompt不能在命令之間退出或關閉。

我的當前代碼如下所示,允許執行一系列程序,但這些命令必須以某種方式傳送到shell /命令提示符中,從中必須讀取輸出。

ArrayList<String> comDat = new ArrayList<>(); 

while(true) { 
    String input = con.recv(); 
    System.out.println("> " + input); 

    if(!input.equals("EOF")) comDat.add(input); else { 
     String[] s = new String[comDat.size()]; 
     for(int i = 0; i < comDat.size(); i++) s[i] = comDat.get(i); 

     System.out.println("---Command sequence executing---"); 
     Process p = Runtime.getRuntime().exec(s); 
     p.waitFor(); 

     System.out.println("---ErrorStream output---"); String line = ""; 
     BufferedReader errStream = new BufferedReader(new InputStreamReader(p.getErrorStream())); 
     while((line = errStream.readLine()) != null) System.out.println("< " + line); 

     System.out.println("\n---OutputStream output---"); line = ""; 
     BufferedReader outStream = new BufferedReader(new InputStreamReader(p.getInputStream())); 
     while((line = errStream.readLine()) != null) System.out.println("< " + line); 
    } 
    Thread.sleep(200); 
} 

感謝您的幫助!

+1

「目錄」是不是一個可執行的命令,它是命令處理程序的一部分,你需要通過@MadProgrammer我已經意識到「CMD」 – MadProgrammer

+0

執行它是 - 仍然不知道該怎麼做,在這種一種通用於平臺的方式。 – Zyerah

+0

對不起,檢查出一些答案,嘗試看看[這](http://stackoverflow.com/questions/4031390/executing-dos-commands-from-java) – MadProgrammer

回答

0

基本前提反駁dir不是外部命令,而是cmd的功能。

當讀取一個進程的輸出時,我會避免使用BufferedReaders,因爲並不是所有進程在發送輸出時都使用新行(例如進度指示器),而應該讀取char(char)char(IMHO)。

您應該將我們ProcessBuilder而不是Runtime#exec。它提供了更好的管理,並允許您將錯誤流重定向到輸入流中,從而更易於讀取輸入。

import java.io.IOException; 
import java.io.InputStream; 

public class TestProcessBuilder { 

    public static void main(String[] args) { 

     try { 
      ProcessBuilder pb = new ProcessBuilder("cmd", "/c", "dir"); 
      pb.redirectError(); 
      Process p = pb.start(); 
      InputStreamConsumer isc = new InputStreamConsumer(p.getInputStream()); 
      isc.start(); 
      int exitCode = p.waitFor(); 

      isc.join(); 
      System.out.println("Process terminated with " + exitCode); 
     } catch (IOException | InterruptedException exp) { 
      exp.printStackTrace(); 
     } 

    } 

    public static class InputStreamConsumer extends Thread { 

     private InputStream is; 

     public InputStreamConsumer(InputStream is) { 
      this.is = is; 
     } 

     @Override 
     public void run() { 

      try { 
       int value = -1; 
       while ((value = is.read()) != -1) { 
        System.out.print((char)value); 
       } 
      } catch (IOException exp) { 
       exp.printStackTrace(); 
      } 

     } 

    } 
} 
+0

除了'ProcessBuilder'沒有辦法運行第二個命令;我需要在同一提示符下運行多個順序命令。 – Zyerah

+0

那麼? 'Runtime#exec'也沒有,你只需要繼續創建新的實例。實際上,我只寫了一個類,它很好地包裝了這個類並提供了線程回調。所以,現在我只是傳遞一系列'字符串'給班級附加一個聽衆,並且瞧... – MadProgrammer

+0

但是這是我的問題的一點:我需要在相同的提示中的命令。 – Zyerah