Java 捕获终端输出

Java catching terminal output

我目前正在尝试在 linux shell 中为 de/encoding base64 编写 Java 文件。我目前使用的方法是:

public static String cmdExec(String Base64String) throws java.io.IOException, java.lang.InterruptedException{
    String line;

    try {
        Process p = Runtime.getRuntime().exec("openssl enc -base64 -d <<< " + Base64String);
        BufferedReader input = new BufferedReader
            (new InputStreamReader(p.getInputStream()));
             while ((line = input.readLine()) != null) {
            output += (line);
        }
        input.close();
        }
    catch (Exception ex) {
        ex.printStackTrace();
    }
    System.out.println(output);
    return output;
}

不幸的是,如果我在 shell.
中手动输入命令,尽管命令正在运行,但我没有得到输出 我知道自 Java 8 以来有一个 Java 编码器,还有 apache 解决方案,但我真的很想通过命令行让它工作。

我做错了什么吗?

也许可以尝试 Scanner:

String output = "";
Process p = Runtime.getRuntime().exec("openssl enc -base64 -d <<< "+cmdLine);
Scanner s = new Scanner(p.getInputStream()).useDelimiter("\A");
while (s.hasNext()) {
  output += s.next();
}
s.close();

它不起作用,因为 child 不是 shell 中的 运行,因此尝试的重定向实际上被视为 openssl 的参数。因此 openssl 抱怨 <<< 是一个无效选项。您可以通过 p.getErrorStream() 以与标准输出相同的方式捕获和打印 child 的标准错误来看到这一点。 child 进程的退出值也可用于 p.exitValue() - 你也应该检查一下。

现在,Base64String 参数是您要解码的 base64 编码文本,因此您需要将该文本作为输入发送到 child。您可以使用 p.getOuputStream() 获取 child 的标准输入,然后写入流:

Process p = Runtime.getRuntime().exec("openssl enc -base64 -d");
// Process p = Runtime.getRuntime().exec("base64 -d");    // the base64 command also works
BufferedWriter toChild = new BufferedWriter(
                             new OutputStreamWriter(p.getOutputStream()));
toChild.write(Base64String + "\n");
toChild.close();

关闭 child 的标准输入后,您可以像现在一样使用 p.getInputStream() 读取解码输出。如上所述,您应该检查 child 的退出值(non-zero 表示 child 发生错误),并收集 child 的 stderr,以便退出值为non-zero.

即可显示

最后一件事,命令 base64 -d 也可以工作,通常作为核心 linux 实用程序存在,不需要安装 openssl