如何将字符串参数传递给使用Apache Commons Exec启动的可执行文件?
我需要将一个文本参数传递给使用Apache Commons Exec启动的命令的stdin(对于好奇,命令是gpg,参数是密钥库的密码; gpg没有明确提供密码的参数,仅从stdin接受它。
另外,我需要它来支持Linux和Windows。
在shell脚本中,我会这样做
cat mypassphrase|gpg --passphrase-fd
要么
type mypassphrase|gpg --passphrase-fd
但是类型在Windows上不起作用,因为它不是可执行文件,而是命令内置的命令(cmd.exe)。
代码不起作用(出于上述原因)如下。 为此产生一个完整的shell太难看了,我一直在寻找更优雅的解决方案。 不幸的是,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);
您不能添加管道参数( |
),因为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"));
这应该相当于键入echo "hello" | sed s/hello/goodbye/
echo "hello" | sed s/hello/goodbye/
into( bash
)shell(尽管UTF-8可能是更合适的编码)。
嗨,要做到这一点,我将使用这样一个小帮助类: https : //github.com/Macilias/Utils/blob/master/ShellUtils.java
基本上你可以在不事先调用bash的情况下模拟之前显示的管道使用情况:
public static String runCommand(String command, Optional 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 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; }
- 属性文件未使用Apache Commons Configuration反映修改的更改
- 如何从绝对文件路径制作CommonsMultipartFile?
- Apache commons fileupload FileItemIterator hasNext()返回false
- 使用Linux上的Apache Commons Compression压缩文件时编码错误
- 添加到WEB-INF / lib的jar文件在我尝试导入时无法识别:说包不存在
- apache commons net ssl握手错误与android
- 使用org.apache.commons.net.ftp.FTPClient保护FTP
- html多部分表单中输入文本字段的值
- Java BeanUtilsBean:将Date转换为String