JAVA中进程的输入始终挂起

时间:2014-12-13 14:08:48

标签: java

关注this 我有一个JAVA代码来做sudo -l,但它总是挂起来。顺便说一下,无论我使用

Reader stdOut = new InputStreamReader (p.getInputStream ())

Reader stdOut = new InputStreamReader (p.getErrorStream ())

john"的输出" [sudo]密码似乎我的代码没有阅读。来自哪里?

这是我的代码

     Process p= Runtime.getRuntime ().exec (new String[] {"sudo", "-l"});

     Reader stdOut = new InputStreamReader (p.getErrorStream ());
     BufferedReader reader = new BufferedReader(stdOut);

     StringBuffer output = new StringBuffer();
     String line = "";           
     while ((line = reader.readLine())!= null) {
         System.out.println("$$" + line);
         if (line.contains ("password"))  {
               break;
         }
     }

    OutputStream stdIn = p.getOutputStream ();
    stdIn.write ("<my password>\n".getBytes ("US-ASCII"));
    stdIn.flush ();

     while ((line = reader.readLine())!= null) {
         System.out.println(line);
     }

2 个答案:

答案 0 :(得分:1)

Sudo通常会打开/dev/tty来提示并读取密码。重定向标准输入或标准输出不会影响与过程相关的tty。

尝试使用-S参数运行sudo。它会导致sudo将提示写入标准错误并从标准输入读取密码。请参阅sudo manual

答案 1 :(得分:1)

readLine阻止直到到达行尾或流结束,但sudo不会在密码后打印换行符或回车符。

所以你应该像char一样读取char char:

String line;
char c;
do {
    line = null;
    while ((c = (char) p.getInputStream().read()) != -1) {
      if(c == '\r' || c == '\n') {
          break;
      }
      if(line==null){
          line="";
      }
      line+=String.valueOf(c);
        if (line != null) { 
            if(line.contains("password")) {//Attention: Ask for the very last word,
                                          //including ':' if sudo prints that out
                break;
            }
        }
    }
    if (line != null) { 
        System.out.println("$$" + line);
        if(line.contains("password")) {//Attention: Ask for the very last word,
                                       //including ':' if sudo prints that out
            break;
        }
    }
}while(c != -1);

我认为这会有效,但我也确信代码可以写得更清楚 此外,您应该考虑使用ProcessBuilder,而不是将输出和错误流合并为

ProcessBuilder.redirectErrorStream(true)