【问题标题】:using cmd with in responsive mode in c++ or java在 c++ 或 java 中以响应模式使用 cmd
【发布时间】:2012-11-27 07:21:45
【问题描述】:

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

【问题讨论】:

  • 你能告诉我你想做什么吗??
  • @ZainShah120 我正在尝试使用 OpenSSL 创建证书..我想给 OpenSSL 命令一个用户界面..
  • 也许这会有所帮助:superuser.com/questions/375078/…
  • @JesperGaarsdal 它只有助于创建批处理文件
  • 恕我直言,您应该使用 OpenSSL 库而不是外壳,如下所述:stackoverflow.com/questions/256405/…

标签: java c++ openssl cmd exec


【解决方案1】:

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

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

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

【讨论】:

  • 所以我们也可以在 .NET 中简单地做到这一点吗?你以前用 openssl 做过这个吗?
  • 重点是从任何给定语言执行命令通常都非常简单。棘手的是交互部分,因此如果您可以提前构建命令和/或配置,并以不需要任何交互的模式执行它,您的工作就会轻松很多。
【解决方案2】:

在 Java 中足够简单。只是:

  1. 获取Process 句柄。
  2. 阅读Process' input stream 以获取写入标准输出的提示。
  3. 回复提示至Process' output stream

这是一个快速的 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 系统属性

【讨论】:

  • 如果要求是/否我该怎么办?
  • @user1765876:用 Java 代码更新了我的答案。无论它想让你输入什么,我都会在示例中输入your response
  • 我会采用同样的方法。为此+1。但在我的脑海里,我想避免这种情况,我必须继续阅读 stdout 才能继续这个过程。
  • @Kazekage:我只在 Java 这方面有经验。出于好奇,对于这个问题,您更喜欢什么?
  • @RyanStewart 我会走同样的路,正如我已经说过的那样。但是我觉得让我的程序流到stdout手中有点麻烦。
【解决方案3】:

对于 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/

【讨论】:

  • 你在问什么?您可能想要回答的一些问题:是的,如果您从 Java 启动 openssl CLI,您可以传递 -batch 标志。也可以,您可以从 java 运行批处理文件:stackoverflow.com/questions/1421143/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-18
  • 1970-01-01
相关资源
最近更新 更多