我在我的 c++ 应用程序中使用 OpenSSL,问题是如果我使用exec("Open ssl command")
Then 它会执行那个特定的命令,但实际上这个命令是响应式的,我的意思是它进一步问你"Are you sure you want to do this Y/N?"
我不知道如何满足这种情况。我该怎么做使用 java 或 C++ 运行响应式命令行,任何帮助将不胜感激。谢谢
3 回答
在Java中很容易。只是:
- 获取进程句柄。
- 读取Process 的输入流以获取写入标准输出的提示。
- 通过写入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
系统属性
基本上,您只需要确保在命令行上输入所有必需的信息,并使用-batch
以避免进一步的问题,例如:
openssl ca -days 3650 -out client.crt -in client.csr -config \path\to\configs -batch -passin pass:PASSWORD -key password
如果这不适用于任何特定的 openssl 命令,请在您的问题中指定您需要执行哪个命令。
对于 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/)