2010-12-15 72 views
5

運行一個批處理腳本,當我需要從Java執行批處理腳本,一旦啓動它執行一個漫長的(幾秒鐘)的任務,並以下的Java:從Java

1)檢測用戶提示。

2)此後,它顯示提示「密碼:」。

3)然後,用戶輸入密碼並按Enter鍵。

4)然後,腳本完成它的工作。我知道如何從Java中啓動腳本,我知道如何閱讀Java中批處理腳本的輸出,但我不知道如何等待密碼提示出現(我如何知道批處理腳本正在等待密碼輸入)。

所以,我的問題是:如何知道批處理腳本何時打印提示?

此刻,我有以下代碼:

final Runtime runtime = Runtime.getRuntime(); 
final String command = ... ; 

final Process proc = runtime.exec(command, null, this.parentDirectory); 

final BufferedReader input = new BufferedReader(new InputStreamReader(
    proc.getInputStream())); 

String line = null; 

while ((line = input.readLine()) != null) { 
LOGGER.debug("proc: " + line); 
} 

回答

3

這應該做的工作:

public static void main(final String... args) throws IOException, InterruptedException { 
    final Runtime runtime = Runtime.getRuntime(); 
    final String command = "..."; // cmd.exe 

    final Process proc = runtime.exec(command, null, new File(".")); 

    final BufferedReader input = new BufferedReader(new InputStreamReader(proc.getInputStream())); 

    StringBuilder sb = new StringBuilder(); 
    char[] cbuf = new char[100]; 
    while (input.read(cbuf) != -1) { 
     sb.append(cbuf); 
     if (sb.toString().contains("Password:")) { 
      break; 
     } 
     Thread.sleep(1000); 
    } 
    System.out.println(sb); 
} 
+0

你確定它是的getOutputStream()?目前,我可以使用input.readLine()看到批處理腳本輸出的一部分(請參閱我的代碼片段中的日誌記錄語句)。但並非全部 - 我無法以這種方式檢測提示。 – 2010-12-15 13:30:20

+0

我的第一個回答是廢話。 javadoc解釋了輸出和輸入流:http://download.oracle.com/javase/6/docs/api/java/lang/Process.html。 – remipod 2010-12-15 13:41:59

+0

感謝您的代碼。不幸的是,密碼提示不會被換行符終止。這就是爲什麼readline在這種情況下不起作用的原因。 – 2010-12-15 14:37:56

1

這一個似乎工作:

@Override 
public void run() throws IOException, InterruptedException { 
    final Runtime runtime = Runtime.getRuntime(); 
    final String command = ...; 

    final Process proc = runtime.exec(command, null, this.parentDirectory); 

    final BufferedReader input = new BufferedReader(new InputStreamReader(
      proc.getInputStream())); 

    String batchFileOutput = ""; 

    while (input.ready()) { 
     char character = (char) input.read(); 
     batchFileOutput = batchFileOutput + character; 
    } 

    // Batch script has printed the banner 
    // Wait for the password prompt 
    while (!input.ready()) { 
     Thread.sleep(1000); 
    } 

    // The password prompt isn't terminated by a newline - that's why we can't use readLine. 
    // Instead, we need to read the stuff character by character. 
    batchFileOutput = ""; 

    while (input.ready() && (!batchFileOutput.endsWith("Password: "))) { 
     char character = (char) input.read(); 
     batchFileOutput = batchFileOutput + character; 
    } 

    // When we are here, the prompt has been printed 
    // It's time to enter the password 

    if (batchFileOutput.endsWith("Password: ")) { 
     final BufferedWriter writer = new BufferedWriter(
       new OutputStreamWriter(proc.getOutputStream())); 

     writer.write(this.password); 

     // Simulate pressing of the Enter key 
     writer.newLine(); 

     // Flush the stream, otherwise it doesn't work 
     writer.flush(); 
    } 

    // Now print out the output of the batch script AFTER we have provided it with a password 
    String line; 

    while ((line = input.readLine()) != null) { 
     LOGGER.debug("proc: " + line); 
    } 

    // Print out the stuff on stderr, if the batch script has written something into it 
    final BufferedReader error = new BufferedReader(new InputStreamReader(
      proc.getErrorStream())); 

    String errorLine = null; 

    while ((errorLine = error.readLine()) != null) { 
     LOGGER.debug("proc2: " + errorLine); 
    } 

    // Wait until the program has completed 

    final int result = proc.waitFor(); 

    // Log the result 
    LOGGER.debug("result: " + result); 
}