关注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);
}
答案 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)