[英]Java: read input prompt from terminal
I'm creating a process in Java that runs ssh-keygen in Linux. 我正在用Java创建一个在Linux中运行ssh-keygen的进程。 This utility normally takes user input from the terminal, so I need to send responses from within my Java program.
该实用程序通常从终端接收用户输入,因此我需要从Java程序中发送响应。 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.
当ssh-keygen要求用户输入时,这似乎卡在fromProc.hasNextLine()上。 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.
我在想也许可以将fromProc.useDelimiter()与换行符结合使用,但是我不确定是什么原因,因为提示往往以空格结尾。
Alternatively, could this be done more easily with a bash script? 或者,可以使用bash脚本更轻松地完成此操作吗? 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.
不幸的是,我对bash的经验很少,并且我不确定当ssh-keygen的提示每次可能不同时是否可以模拟用户输入。 The Java code I have here is intended to be flexible in that it only responds to certain prompts if they appear.
我在这里使用的Java代码旨在具有灵活性,因为它仅对某些提示(如果出现)进行响应。
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.
它实际上是嵌入式代码,因此我不必担心可移植性。
To scan for a phrase without an end-of-line you should probably use Scanner.findInLine
. 要扫描没有行尾的短语,您可能应该使用
Scanner.findInLine
。
However, I don't think your troubles will end there. 但是,我认为您的麻烦不会到此为止。 The ssh-keygen outputs some of the prompts to its associated tty (and expects the answers from there) rather than standard output and standard input.
ssh-keygen将一些提示输出到与其关联的tty(并希望从那里得到答案),而不是标准输出和标准输入。 In fact, I've just tested it out of curiosity, and it gives one prompt on standard error and one on standard output, and then the next one on tty.
实际上,出于好奇,我刚刚对其进行了测试,它针对标准错误给出了一个提示,针对标准输出给出了一个提示,然后针对tty提供了下一个提示。
Why don't you avoid all that and pass the name of the file, the passphrase and all that as parameters to the ssh-keygen command? 为什么不避免所有这些,而是将文件名,密码短语和所有这些参数作为参数传递给ssh-keygen命令?
You can see how in this answer . 您可以在此答案中看到。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.