2011-01-14 57 views
11

我需要管文本参数与Apache下议院Exec的(为好奇推出了命令的标准输入,命令GPG和参数是密码密钥库; GPG没有一个说法,明确规定了密码,只能从stdin接受它)。如何将字符串参数传递给使用Apache Commons Exec启动的可执行文件?

另外,我想这能同时支持Linux和Windows。

在一个shell脚本,我会做

cat mypassphrase|gpg --passphrase-fd 

type mypassphrase|gpg --passphrase-fd 

,但因为它不是解释的可执行文件,但内置的命令的命令(CMD类型不工作在Windows上。可执行程序)。

代码不工作(由于上述原因)低于。为此产生一个完整的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); 

回答

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")); 

这应该是打字echo "hello" | sed s/hello/goodbye/成(bash)壳(虽然UTF-8可以是更适当的编码)的等价物。

+0

很不错的答案!拯救了我的一天! – BetaRide 2012-03-15 07:46:38

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; 
} 
相关问题