我正在用Java创建一个在Linux中运行ssh-keygen的进程。该实用程序通常从终端获取用户输入,因此我需要从我的Java程序中发送响应。以下是在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();
}
}
现在针对这个问题,以及为什么我之前提到的问题不足。当ssh-keygen要求用户输入时,这似乎停留在fromProc.hasNextLine()上。我怀疑这是因为要求用户输入的行不以换行符结束(因为直接在终端中输入的响应会出现在与提示相同的行上)。
所以这是我的问题。如果它们不以换行符结尾,我该如何阅读提示行?我想我可以使用fromProc.useDelimiter()替换换行符,但我不完全确定是什么,因为提示往往只是以空格结尾。
或者,使用bash脚本可以更轻松地完成此操作吗?不幸的是我对bash的经验不多,我不确定当ssh-keygen的提示每次都有所不同时是否可以模拟用户输入。我在这里的Java代码旨在灵活,因为它只响应某些提示,如果它们出现。
免责声明:此操作仅在具有非常特定系统详细信息的已知计算机上运行。它是有效的嵌入式代码,所以我不需要担心可移植性。
答案 0 :(得分:2)
要扫描没有行尾的词组,您应该使用Scanner.findInLine
。
但是,我不认为你的麻烦会在那里结束。 ssh-keygen将一些提示输出到其关联的tty(并期望从那里得到答案)而不是标准输出和标准输入。事实上,我只是出于好奇而对它进行了测试,它给出了标准错误的一个提示和标准输出的一个提示,然后是关于tty的下一个提示。
为什么不避免这一切,并将文件名,密码和所有参数传递给ssh-keygen命令?
您可以在this answer中看到。