10

我在我的 c++ 应用程序中使用 OpenSSL,问题是如果我使用exec("Open ssl command") Then 它会执行那个特定的命令,但实际上这个命令是响应式的,我的意思是它进一步问你"Are you sure you want to do this Y/N?" 我不知道如何满足这种情况。我该怎么做使用 java 或 C++ 运行响应式命令行,任何帮助将不胜感激。谢谢

4

3 回答 3

9

在Java中很容易。只是:

  1. 获取进程句柄。
  2. 读取Process 的输入流以获取写入标准输出的提示。
  3. 通过写入Process 的输出流来响应提示。

这是一个快速的 Groovy 示例,因为它比 Java 更容易:

def cmd = ... // the command you want to run
def process = cmd.execute()
def processStdout = new Scanner(process.inputStream)
def processStdin = process.outputStream
def outputLine = processStdout.nextLine()
if (outputLine == 'some prompt written to stdout') {
    processStdin << 'your response\n'
}

如果你跟不上 Groovy,我可以把它扩展成 Java。

请注意,此示例不处理确保嵌套进程的 stdout 和 stderr 被完全消耗以防止阻塞的潜在重要任务,也不处理确保进程干净退出的处理。

更新:这是 Java 中的相同内容:

import java.io.OutputStream;
import java.util.Scanner;

public class SubprocessIO {
    public static void main(String[] args) throws Exception {
        String[] cmd = { ... your command as a series of strings ... };
        Process process = Runtime.getRuntime().exec(cmd);
        Scanner processStdout = new Scanner(process.getInputStream());
        OutputStream processStdin = process.getOutputStream();
        String outputLine = processStdout.nextLine();
        if (outputLine.equals("some prompt written to stdout")) {
            processStdin.write("your response\n".getBytes());
            processStdin.flush();
        }
    }
}

我忘记在第一次循环中记\n下响应中的 至关重要,假设应用程序希望您输入一些内容然后按 Enter。此外,您最好使用line.separator系统属性

于 2012-12-15T22:14:58.853 回答
6

基本上,您只需要确保在命令行上输入所有必需的信息,并使用-batch以避免进一步的问题,例如:

openssl ca -days 3650 -out client.crt -in client.csr -config \path\to\configs -batch -passin pass:PASSWORD -key password

如果这不适用于任何特定的 openssl 命令,请在您的问题中指定您需要执行哪个命令。

于 2012-12-15T21:26:00.530 回答
2

对于 openssl,Wimmel 的答案是正确的方法。根据您的具体用例,您可能需要准备或构建一个包含重复参数的配置文件,并在命令行上指定不同的参数(以及指向配置文件的指针)。-batch 选项,至少可用于管理证书的常用 openssl 命令将确保不发生交互 - 如果您指定的参数不足,命令将失败。

要运行命令并评估其结果,您仍然需要相应的功能。在 Java 中,您使用 ProcessBuilder 和 Process 类。在 C++ 中没有标准的方法来做到这一点(system() 函数对于大多数用途来说太有限了),因此您需要使用特定于平台的 C 函数(例如 CreateProcess、posix_spawn 或 fork/exec)或找到合适的 C++ 库.

但是对于以编程方式直接回答交互式问题,这些界面可能是不够的。交互式对话可能相当复杂。通常,这并不像将所有输入和输出都视为简单的字符流那么简单。细节取决于平台和程序,但您可能需要类似 expect 的东西(参见http://en.wikipedia.org/wiki/Expect)来处理这个问题。

更新:当然,为所有这些调用外部 CLI 的方法不一定是最好的,并且引入了一组全新的无关副作用。您最好使用合适的加密 API(例如 BouncyCastle http://www.bouncycastle.org/

于 2012-12-17T23:18:01.183 回答