11

Apache Commons Exec で起動されたコマンドの stdin にテキスト引数をパイプする必要があります (興味深いことに、コマンドは gpg で、引数はキーストアへのパスフレーズです。gpg にはパスフレーズを明示的に提供する引数がありません。標準入力から受け入れる)。

さらに、Linux と Windows の両方をサポートするためにこれが必要です。

私がするシェルスクリプトで

cat mypassphrase|gpg --passphrase-fd

また

type mypassphrase|gpg --passphrase-fd

ただし、タイプは実行可能ファイルではなく、解釈されたコマンド (cmd.exe) に組み込まれたコマンドであるため、Windows では機能しません。

(上記の理由で)動作しないコードは以下のとおりです。これのためにシェル全体を生成するのはあまりにも醜いので、よりエレガントなソリューションを探していました。残念ながら、BouncyCastle ライブラリと PGP の間にはいくつかの非互換性の問題があるため、(非常に短い) 時間内に完全にプログラム化されたソリューションを使用することはできません。

前もって感謝します。

CommandLine cmdLine = new CommandLine("type");
cmdLine.addArgument(passphrase);
cmdLine.addArgument("|");
cmdLine.addArgument("gpg");
cmdLine.addArgument("--passphrase-fd");
cmdLine.addArgument("0");
cmdLine.addArgument("--no-default-keyring");
cmdLine.addArgument("--keyring");
cmdLine.addArgument("${publicRingPath}");
cmdLine.addArgument("--secret-keyring");
cmdLine.addArgument("${secretRingPath}");
cmdLine.addArgument("--sign");
cmdLine.addArgument("--encrypt");
cmdLine.addArgument("-r");
cmdLine.addArgument("recipientName");
cmdLine.setSubstitutionMap(map);
DefaultExecutor executor = new DefaultExecutor();
int exitValue = executor.execute(cmdLine);
4

2 に答える 2

17

コマンドはパイプ引数()を受け入れない|ため、パイプ引数()を追加することはできません。パイプを解釈し、そのコマンドラインをシェルに入力すると特別な処理を行うgpgのはシェル(例)です。bash

ByteArrayInputStreamコマンドの標準入力にデータを手動で送信するために使用できます(コマンドが表示bashされる場合と同様|)。

    Executor exec = new DefaultExecutor();

    CommandLine cl = new CommandLine("sed");
            cl.addArgument("s/hello/goodbye/");

    String text = "hello";
    ByteArrayInputStream input =
        new ByteArrayInputStream(text.getBytes("ISO-8859-1"));
    ByteArrayOutputStream output = new ByteArrayOutputStream();

    exec.setStreamHandler(new PumpStreamHandler(output, null, input));
    exec.execute(cl);

    System.out.println("result: " + output.toString("ISO-8859-1"));

これはecho "hello" | sed s/hello/goodbye/、(bash)シェルに入力するのと同じです(ただし、UTF-8の方が適切なエンコーディングである可能性があります)。

于 2011-01-20T20:02:47.220 に答える
0

こんにちは、これを行うには、次のような小さなヘルパー クラスを使用します: https://github.com/Macilias/Utils/blob/master/ShellUtils.java

基本的に、事前に bash を呼び出さずに、前に示したようにパイプの使用法をシミュレートできます。

public static String runCommand(String command, Optional<File> dir) throws IOException {
    String[] commands = command.split("\\|");
    ByteArrayOutputStream output = null;
    for (String cmd : commands) {
        output = runSubCommand(output != null ? new ByteArrayInputStream(output.toByteArray()) : null, cmd.trim(), dir);
    }
    return output != null ? output.toString() : null;
}

private static ByteArrayOutputStream runSubCommand(ByteArrayInputStream input, String command, Optional<File> dir) throws IOException {
    final ByteArrayOutputStream output = new ByteArrayOutputStream();
    CommandLine cmd = CommandLine.parse(command);
    DefaultExecutor exec = new DefaultExecutor();
    if (dir.isPresent()) {
        exec.setWorkingDirectory(dir.get());
    }
    PumpStreamHandler streamHandler = new PumpStreamHandler(output, output, input);
    exec.setStreamHandler(streamHandler);
    exec.execute(cmd);
    return output;
}
于 2016-10-17T16:02:53.387 に答える