JAVA中进程的输入始终挂起

JAVA中进程的输入始终挂起,java,Java,跟随 我有一个JAVA代码来执行sudo-l,但它总是挂起。顺便说一句,不管我是否使用 Reader stdOut = new InputStreamReader (p.getInputStream ()) 或 输出“[sudo]john密码”似乎未被我的代码读取。你从哪里来的 这是我的密码 Process p= Runtime.getRuntime ().exec (new String[] {"sudo", "-l"}); Reader stdOut = new In

跟随 我有一个JAVA代码来执行sudo-l,但它总是挂起。顺便说一句,不管我是否使用

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

输出“[sudo]john密码”似乎未被我的代码读取。你从哪里来的

这是我的密码

     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);
     }
processp=Runtime.getRuntime().exec(新字符串[]{“sudo”,“-l”});
Reader stdOut=newInputStreamReader(p.getErrorStream());
BufferedReader reader=新的BufferedReader(标准输出);
StringBuffer输出=新的StringBuffer();
字符串行=”;
而((line=reader.readLine())!=null){
System.out.println(“$$”+行);
if(line.contains(“密码”)){
打破
}
}
OutputStream stdIn=p.getOutputStream();
stdIn.write(“\n”.getBytes(“US-ASCII”);
stdIn.flush();
而((line=reader.readLine())!=null){
系统输出打印项次(行);
}

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


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

读取行块,直到到达行尾或流尾,但sudo不会在密码后打印换行或回车。

因此,您应该逐字符读取流,如下所示:

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)

在shell上尝试基本重定向。我怀疑提示符将转到stderr.2>&1。这也没用。
2>&1
是一个shell重定向,在这里不会有任何效果。不确定为什么打开/dev/tty是个好主意。不知道sudobetter是否使用-S作为默认行为。
ProcessBuilder.redirectErrorStream(true)