Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何通过管道将字符串参数传递到使用ApacheCommonsExec启动的可执行文件?_Java_Apache Commons_Apache Commons Exec - Fatal编程技术网

Java 如何通过管道将字符串参数传递到使用ApacheCommonsExec启动的可执行文件?

Java 如何通过管道将字符串参数传递到使用ApacheCommonsExec启动的可执行文件?,java,apache-commons,apache-commons-exec,Java,Apache Commons,Apache Commons Exec,我需要通过管道将一个文本参数传递到使用ApacheCommonsExec启动的命令的stdin(出于好奇,该命令是gpg,参数是密钥库的密码短语;gpg没有一个参数来显式提供密码短语,只是从stdin接受它) 此外,我需要它来支持Linux和Windows 在shell脚本中,我会这样做 cat mypassphrase|gpg --passphrase-fd 或 但是类型在Windows上不起作用,因为它不是一个可执行文件,而是一个内置于命令解释(cmd.exe)中的命令 代码不工作(出于上

我需要通过管道将一个文本参数传递到使用ApacheCommonsExec启动的命令的stdin(出于好奇,该命令是gpg,参数是密钥库的密码短语;gpg没有一个参数来显式提供密码短语,只是从stdin接受它)

此外,我需要它来支持Linux和Windows

在shell脚本中,我会这样做

cat mypassphrase|gpg --passphrase-fd

但是类型在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);

无法添加管道参数(
|
),因为
gpg
命令不接受该参数。在shell中键入命令行时,解释管道并执行特殊处理的是shell(例如,
bash

您可以使用
ByteArrayInputStream
手动将数据发送到命令的标准输入端(就像
bash
看到
|
时所做的那样)


这应该相当于在(
bash
)shell中键入
echo“hello”| sed s/hello/debye/
(尽管UTF-8可能是更合适的编码)。

要做到这一点,我将使用一个类似以下的小助手类:

基本上,您可以模拟管道使用情况,如前所示,而无需事先调用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;
}
publicstaticstringruncommand(stringcommand,可选dir)抛出IOException{
String[]commands=command.split(“\\\\”);
ByteArrayOutputStream输出=null;
for(字符串cmd:commands){
output=runSubCommand(output!=null?新建ByteArrayInputStream(output.toByteArray()):null,cmd.trim(),dir);
}
返回输出!=null?output.toString():null;
}
私有静态ByteArrayOutputStream runSubCommand(ByteArrayInputStream输入,String命令,可选dir)引发IOException{
最终ByteArrayOutputStream输出=新建ByteArrayOutputStream();
CommandLine cmd=CommandLine.parse(命令);
DefaultExecutor exec=新的DefaultExecutor();
if(dir.isPresent()){
setWorkingDirectory(dir.get());
}
PumpStreamHandler streamHandler=新的PumpStreamHandler(输出、输出、输入);
执行setStreamHandler(streamHandler);
exec.execute(cmd);
返回输出;
}
    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"));
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;
}