C++ アプリで OpenSSL を使用しています。問題は、使用exec("Open ssl command")
すると、その特定のコマンドが実行されますが、実際にはこのコマンドは反応的です。つまり、"Are you sure you want to do this Y/N?"
このシナリオに対応する方法がわかりません。 Java または C++ を使用して、応答性の高いコマンド ラインを実行します。ありがとう
3 に答える
Javaでは十分簡単です。ただ:
- プロセスハンドルを取得します。
- stdoutに書き込まれたプロンプトについては、プロセスの入力ストリームを読み取ります。
- プロセスの出力ストリームに書き込むことにより、プロンプトに応答します。
これは、Javaよりもさらに簡単なGroovyの簡単なサンプルです。
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/ )を使用する方がよい場合があります。