如何将字符串参数通过管道传递给使用 Apache Commons Exec 启动的可执行文件? [英] How to pipe a string argument to an executable launched with Apache Commons Exec?
问题描述
我需要通过管道将文本参数传递给使用 Apache Commons Exec 启动的命令的 stdin(出于好奇,命令是 gpg,参数是密钥库的密码;gpg 没有提供密码的参数明确地,只从标准输入接受它).
I need to pipe a text argument to the stdin of a command launched with Apache Commons Exec (for the curious, the command is gpg and the argument is the passphrase to the keystore; gpg does not have an argument to provide the passphrase explicitly, only to accept it from stdin).
此外,我需要它来支持 Linux 和 Windows.
In addition, I need this to support both Linux and Windows.
在shell脚本中我会做
In a shell script I'd do
cat mypassphrase|gpg --passphrase-fd
或
type mypassphrase|gpg --passphrase-fd
但 type 在 Windows 上不起作用,因为它不是可执行文件,而是内置于已解释命令 (cmd.exe) 中的命令.
but type doesn't work on Windows as it's not an executable but a command built into the command interpreted (cmd.exe).
不工作的代码(由于上述原因)如下.为此生成整个外壳太难看了,我一直在寻找更优雅的解决方案.不幸的是,BouncyCastle 库和 PGP 之间存在一些不兼容问题,因此我无法在(非常短的)时间内使用完全编程的解决方案.
The code not working (for the above reason) is below. To spawn an entire shell for this is too ugly, I was looking for a more elegant solution. Unfortunately, there are some incompatibility problems between the BouncyCastle library and PGP so I cannot use a fully programmatic solution in the (very short) time I have.
提前致谢.
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);
推荐答案
您不能添加管道参数 (|
),因为 gpg
命令不会接受它.是 shell(例如 bash
)解释管道并在您在 shell 中键入该命令行时进行特殊处理.
You cannot add a pipe argument (|
) because the gpg
command won't accept that. It's the shell (e.g. bash
) that interprets the pipe and does special processing when you type that commandline into the shell.
您可以使用 ByteArrayInputStream
手动将数据发送到命令的标准输入(很像 bash
在看到 |
时所做的).
You can use ByteArrayInputStream
to manually send data to the standard input of a command (much like bash
does when it sees the |
).
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
) shell(尽管 UTF-8 可能是更合适的编码).
This should be the equivalent of typing echo "hello" | sed s/hello/goodbye/
into a (bash
) shell (though UTF-8 may be a more appropriate encoding).
这篇关于如何将字符串参数通过管道传递给使用 Apache Commons Exec 启动的可执行文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!