简体   繁体   English

Java:从终端读取输入提示

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM