如何通过管道将字符串参数传递给使用 Apache Commons Exec 启动的可执行文件?
我需要将文本参数通过管道传输到使用 Apache Commons Exec 启动的命令的标准输入(出于好奇,该命令是 gpg,参数是密钥库的密码;gpg 没有显式提供密码的参数,仅从标准输入接受它)。
另外,我需要这个来支持Linux和Windows。
在 shell 脚本中,我会执行
cat mypassphrase|gpg --passphrase-fd
or
type mypassphrase|gpg --passphrase-fd
但 type 在 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);
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).
In addition, I need this to support both Linux and Windows.
In a shell script I'd do
cat mypassphrase|gpg --passphrase-fd
or
type mypassphrase|gpg --passphrase-fd
but type doesn't work on Windows as it's not an executable but a command built into the command interpreted (cmd.exe).
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.
Thanks in advance.
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);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您无法添加管道参数 (
|
),因为gpg
命令不会接受该参数。当您在 shell 中键入命令行时,shell(例如bash
)会解释管道并进行特殊处理。您可以使用 ByteArrayInputStream 手动将数据发送到命令的标准输入(就像 bash 看到
|
时所做的那样)。这应该相当于输入 echo "hello" | sed s/hello/goodbye/ 进入 (
bash
) shell(尽管 UTF-8 可能是更合适的编码)。You cannot add a pipe argument (
|
) because thegpg
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.You can use
ByteArrayInputStream
to manually send data to the standard input of a command (much likebash
does when it sees the|
).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).嗨,要做到这一点,我将使用一个像这样的小助手类: https://github .com/Macilias/Utils/blob/master/ShellUtils.java
基本上,您可以像之前所示那样模拟管道使用情况,而无需事先调用 bash:
Hi to do this i will use a little helper class like this: https://github.com/Macilias/Utils/blob/master/ShellUtils.java
basically you can than simulate the pipe usage like shown here before without calling the bash beforehand: