如何将字符串参数传递给使用Apache Commons Exec启动的可执行文件?

wis*_*ame 11 java apache-commons apache-commons-exec

我需要将一个文本参数传递给使用Apache Commons Exec启动的命令的stdin(对于好奇,命令是gpg,参数是密钥库的密码; gpg没有明确提供密码的参数,仅从stdin接受它.

另外,我需要它来支持Linux和Windows.

在shell脚本中,我会这样做

cat mypassphrase|gpg --passphrase-fd
Run Code Online (Sandbox Code Playgroud)

要么

type mypassphrase|gpg --passphrase-fd
Run Code Online (Sandbox Code Playgroud)

但是类型在Windows上不起作用,因为它不是可执行文件,而是命令内置的命令(cmd.exe).

代码不工作(由于上述原因)低于.为此产生一个完整的外壳太难看了,我一直在寻找更优雅的解决方案.不幸的是,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);
Run Code Online (Sandbox Code Playgroud)

Pat*_*ick 17

您无法添加管道参数(|),因为该gpg命令不接受该参数.它是shell(例如bash)解释管道并在您将命令行键入shell时进行特殊处理.

您可以使用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"));
Run Code Online (Sandbox Code Playgroud)

这应该等同于键入echo "hello" | sed s/hello/goodbye/(bash)shell(尽管UTF-8可能是更合适的编码).