I'm creating a process in Java that runs ssh-keygen in Linux. This utility normally takes user input from the terminal, so I need to send responses from within my Java program. Here's the relevant code, created with some help from this question:
// Create a process to run ssh-keygen.
ProcessBuilder procBuilder = new ProcessBuilder("ssh-keygen", "-t", "rsa");
// Redirect errors to the process' standard output.
procBuilder.redirectErrorStream(true);
Process proc = procBuilder.start();
Scanner fromProc = new Scanner(new InputStreamReader(proc.getInputStream()));
OutputStream toProc = proc.getOutputStream();
// While there is another line of output from the process. GETS STUCK HERE.
while (fromProc.hasNextLine()) {
String message = fromProc.nextLine();
// If the process asks to overwrite existing keys.
if (message.startsWith("Overwrite (y/n)?") == true) {
// Send response to overwrite RSA keys.
toProc.write("y\n".getBytes());
toProc.flush();
}
// If the message asks to enter a passphrase or specify a file.
else if (message.startsWith("Enter")) {
// Send response to use the default.
toProc.write("\n".getBytes());
toProc.flush();
}
}
Now for the problem, and why the question I linked to earlier falls short. This seems to get stuck on fromProc.hasNextLine() when ssh-keygen is asking for user input. I suspect this is because the line asking for user input doesn't end with a newline character (since a response typed into the terminal directly would appear on the same line as the prompt).
So here's my question. How can I read prompt lines if they don't end in a newline character? I'm thinking I might be able to use fromProc.useDelimiter() with some alternative to the newline character, but I'm not entirely sure what, since prompts tend to just end with a space.
Alternatively, could this be done more easily with a bash script? Unfortunately I have little experience with bash and I'm not sure if it's possible to simulate user input when the prompts from ssh-keygen may differ each time. The Java code I have here is intended to be flexible in that it only responds to certain prompts if they appear.
Disclaimer: this will only be run on known machines with very specific system details. It is effectively embedded code, so I don't need to worry about portability.