Я использую OpenSSL в своем приложении С++. Проблема в том, что я использую exec("Open ssl command")
Затем он выполнит эту конкретную команду, но на самом деле эта команда репсонирует, я имею в виду, что она далее просит вас "Are you sure you want to do this Y/N?"
Я не знаю, как удовлетворить этот сценарий. Как я могу использовать java или С++ для запуска командной строки, которая реагирует, Любая помощь будет оценена.
Благодаря
С использованием cmd в режиме ожидания в С++ или java
Ответ 1
Прост в Java. Просто:
- Получить Process дескриптор.
- Прочитайте входной поток Процесс для приглашений, записанных на стандартный вывод.
- Отвечайте на запросы, выполнив запись в поток Процесs > .
Вот быстрый 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
Ответ 2
В основном вам просто нужно убедиться, что вы вводите всю необходимую информацию в командной строке и используйте -batch
, чтобы избежать дополнительных вопросов, например:
openssl ca -days 3650 -out client.crt -in client.csr -config \path\to\configs -batch -passin pass:PASSWORD -key password
Если это не работает для какой-либо конкретной команды openssl, укажите в своем вопросе, какую команду вам нужно выполнить.
Ответ 3
Для openssl ответ Wimmel - правильный подход. В зависимости от вашего конкретного варианта использования вы можете подготовить или создать файл конфигурации, содержащий повторяющиеся параметры, и указать переменные параметры (и указатель на файл конфигурации) в командной строке. Параметр -batch, доступный, по крайней мере, с помощью общих команд openssl для управления сертификатами, гарантирует отсутствие интерактивности - если вы указали недостаточные параметры, команды будут терпеть неудачу.
Для запуска команды и оценки ее результатов вам по-прежнему нужна соответствующая функциональность. В Java вы используете классы ProcessBuilder и Process. В С++ нет стандартного способа сделать это (функция system() слишком ограничена для большинства применений), поэтому вам необходимо использовать C-специфичные для платформы функции (например, CreateProcess, posix_spawn или fork/exec) или найти подходящую библиотеку С++.
Но для прямого ответа на интерактивные вопросы программно эти интерфейсы могут быть недостаточными. Интерактивный диалог может быть довольно сложным. Обычно это не так просто, как обработка всех входных и выходных данных в виде простого символьного потока. Детали зависят от платформы и программы, но вам может понадобиться что-то вроде expect (см. http://en.wikipedia.org/wiki/Expect), чтобы справиться с этим.
Обновление: конечно, подход к вызову внешнего CLI для всего этого не обязательно является лучшим и вводит совершенно новый набор посторонних побочных проблем. Возможно, вам лучше использовать подходящий криптографический API (например, BouncyCastle http://www.bouncycastle.org/)