Reputation: 4582
Following this I have a JAVA code to do sudo -l, but it always hung. Btw, regardless if I use
Reader stdOut = new InputStreamReader (p.getInputStream ())
or
Reader stdOut = new InputStreamReader (p.getErrorStream ())
The output "[sudo] password for john" seems wasn't read by my code. Where did come from?
Here is my code
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);
}
Upvotes: 2
Views: 245
Reputation: 1854
readLine blocks until end of line or end of stream is reached, but sudo does not print a line feed or carriage return after password.
So you should read the stream char by char like so:
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);
I think this will work, but also I am sure that the code could written clearer.
Also you should think about using ProcessBuilder
, than you are able to merge the output and the error stream
ProcessBuilder.redirectErrorStream(true)
Upvotes: 1
Reputation: 25438
Sudo normally opens /dev/tty
to prompt for and read a password. Redirecting standard input or standard output doesn't affect the tty associated with the process.
Try running sudo with the -S
parameter. It causes sudo to write the prompt to standard error and read the password from standard input. See the sudo manual.
Upvotes: 1