2011-01-14 59 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; 
} 
相關問題