Java 运行时命令行进程格式不正确

Java Runtime Command Line process isn't formatted properly

在 运行 man 几乎任何命令到 return 终端命令的手册,运行时执行似乎 return 单词中的几个字母加倍

预计

OPTIONS
       Note  that,  in  order  to  support obsolescent hardware, unzip's usage
       screen is limited to 22 or 23 lines and should therefore be  considered
       only  a  reminder  of  the basic unzip syntax rather than an exhaustive
       list of all possible flags.  The exhaustive list follows:

由java运行时执行return的输出

OOPPTTIIOONNSS
       Note  that,  in  order  to  support obsolescent hardware, _u_n_z_i_p's usage
       screen is limited to 22 or 23 lines and should therefore be  considered
       only  a  reminder  of  the basic _u_n_z_i_p syntax rather than an exhaustive
       list of all possible flags.  The exhaustive list follows:

以下是我从 运行 命令

获取操作的代码
String[] cmd = {"man unzip"};
            Process process = Runtime.getRuntime().exec(cmd);
            BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while (true) {
                line = in.readLine();
                if (line == null) { break; 
                
            }System.out.println(line);
                
                
                }

Runtime.exec 已过时。请改用 ProcessBuilder

手册页可以包含复杂的标记,包括强调的文本。手册页是使用 nroff 解释器输出的,这意味着强调的文本被渲染,就像被发送到旧打印机一样:一个 A 后跟一个退格字符再接着另一个 A 实际上是一个双击 A,终端足够智能,可以将其呈现为粗体字符。类似地,_ 后跟一个退格字符后跟 A 会在终端中产生带下划线的字符,就像在旧打印机上一样。

最简单的解决方案是将 man 的输出通过 cat 进行管道传输。 nroff 解释器将看到输出目的地是另一个进程,而不是终端,并且根本不会尝试呈现粗体或带下划线的文本:

ProcessBuilder man = new ProcessBuilder("man", "unzip");
ProcessBuilder cat = new ProcessBuilder("cat");

man.redirectError(ProcessBuilder.Redirect.INHERIT);
cat.redirectOutput(ProcessBuilder.Redirect.INHERIT);
cat.redirectError(ProcessBuilder.Redirect.INHERIT);

Iterable<Process> processes =
    ProcessBuilder.startPipeline(List.of(man, cat));

for (Process process : processes) {
    process.waitFor();
}

注意 redirectOutputredirectError 的用法。当给定参数 INHERIT 时,这些方法分别导致 ProcessBuilder 创建的任何进程的标准输出和标准错误出现在程序自己的标准输出或标准错误中。这消除了显式读取输出并打印它的需要。

在Java8中,ProcessBuilder.startPipeline和List.of不可用。 Java 8 兼容的方法来实现这一点是使用 shell 作为管道:

ProcessBuilder builder = new ProcessBuilder("sh", "-c", "man unzip | cat");
builder.inheritIO();

Process process = build.start();
process.waitFor();

在这种情况下,inheritIO() 执行与 redirectOutput(INHERIT)redirectError(INHERIT) 组合相同的功能:外部进程的标准输出和标准错误出现在 Java 进程自己的标准输出和标准错误,因此无需显式读取和打印输出。