可以通过UnixCygwin工具在Windows for Vim上清洁Javac输出

问题描述

我是Java新手,并在Windows 10上安装了以下JDK:

C:\Program Files\AdoptOpenJDK\jdk-11.0.8.10-openj9

我可以从Cygwin的Bash命令行调用编译器javac (在x终端中),但它会创建许多似乎会导致错误错误 stdoutstderr都没有。 我需要将它们发送到文件中 我可以仔细阅读Vim。

这是我的调用命令

# mk.bash
# -------
javac \
-classpath "/c/Program Files/.../cplex.jar" \
TestSetup.java

classpath参数在这里是不相关的,因为我 只想专注于在Vim易读的环境中捕获javac输出 方式。

发出./mk.bash >| mk.out会产生一个空的mk.out,就像这样 ./mk.bash 2>&1 >| mk.out。我使用后一种模式已有几十年了 将stderr重定向到stdout并覆盖目标文件

可以使用script命令将javac输出发送到mk.out

script mk.out
./mk.bash
exit

然后我可以使用Vim浏览错误消息。然而 内容被许多二进制字符(图像和下面的文件链接)所混淆。通常我可以 使用dos2unix清理杂乱的文件,但是在此输出中,该文件因应退出 到二进制字符。

作为清理非文本内容的另一种方法,Vim有一个 可以使用fileformat=dos输入的:e ++ff=dos %选项。 e%说编辑当前文件,而++ff=dos说 将文件解释为dos格式(fffileformat)。所有 这确实是清理了由于线条不同而造成的视觉伪影 以Unix和DOS结尾。所有错误消息仍然散布 与看起来像转义字符^[的东西。

有什么方法可以使javac生成纯文本 输出还是清理输出

这是Vim中非纯文本文件的图像:

enter image description here

我怀疑这一切是否相关,但我正在关注此网页 编译一个简单的Java应用程序TestSetup.java调用第三方 工具:https://kunlei.github.io/cplex/cplex-java-setup

解决方法

最下面的底线

以下Bash命令同时发送stdoutstderr javac到屏幕和文件mk.out

javac -classpath /Some/NonExistent/Jar/File.jar TestSetup.java \
2>&1 | tee mk.out

如何找到

我发现问题主要出在使用Bash管道, 重定向和script命令。后者负责 ANSI代码。我以前无法确定,因为我可以 无法在没有javac的文件中捕获script错误消息。所以 我首先解决了这个问题,然后将scriptscript的缺失。这是我找到的。

以下bash命令创建一个不带ANSI的DOS格式文件 代码:

javac -classpath '/Some/NonExistent/File.jar' TestSetup.java \
>| mk.out 2>&1

之前,我有:(1) 2>&1 >| mk.out而不是(2) >| mk.out 2>&1。对于选项(1),我认为stderr已针对 stdout,所以我只需要将stdout定向到mk.out

但这不是它的工作方式。在选项(1)中,规范2>&1stderr定向到stdout当前指向的位置,即 屏幕。然后,后续的>| mk.out会引导stdout(并且 only std.outmk.out。不幸的是,这意味着stderr是 仍在屏幕上。 Presto mk.out空着(坏)。

在选项(2)中,stdout首先指向mk.out。后续 2>&1然后将stderr定向到stdout所针对的对象,即 mk.out。因此,javac错误消息被发送到mk.out。 它没有包含ANSI代码,这很好。

虽然选项(2)起作用,但并不理想;错误消息不是 显示在屏幕上。这是我退回到script并发现的地方 它引入了ANSI代码:

script \
-c "javac -classpath '/Some/NonExistent/File.jar' TestSetup.java" \
mk.out

由于上述解决了重定向stderr的问题, 避免使用script的bash选项。以下将stderr发送给 屏幕并转到mk.out

javac -classpath /Some/NonExistent/Jar/File.jar TestSetup.java \
2>&1 | tee mk.out

根据上面选项(1)的解释,它看起来像 应该不起作用,但是当Bash在 管道。具体来说,stderr被重定向到stdout是什么 定向到,但仅在所有重定向之后。在管道中, 上面的意思是javac的{​​{1}}被定向到stdout的{​​{1}}, 然后tee的{​​{1}}指向目标 stdin的{​​{1}},即javac的{​​{1}}。

作为参考:初始解决方案(stderr Xstdout 选项)

我发现我的javac具有专门用于此目的的命令行选项stdout

不幸的是,并非所有我在线找到的tee文档都显示了此选项的可用性。在那种情况下,我发现最直接的解决方案是Vim中的:term cat The/Output/File.Path

该页面上还显示了许多vim选项,以及here

如果需要的话,我发现3个引人入胜的页面供以后参考 相关的是:

提及由stdin组成,但是您需要Ubuntu。