问题描述
我是Java新手,并在Windows 10上安装了以下JDK:
C:\Program Files\AdoptOpenJDK\jdk-11.0.8.10-openj9
我可以从Cygwin的Bash命令行调用编译器javac
(在x终端中),但它会创建许多似乎会导致错误的错误
stdout
或stderr
都没有。 我需要将它们发送到文件中
我可以仔细阅读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
格式(ff
是fileformat
)。所有
这确实是清理了由于线条不同而造成的视觉伪影
以Unix和DOS结尾。所有错误消息仍然散布
与看起来像转义字符^[
的东西。
这是Vim中非纯文本文件的图像:
我怀疑这一切是否相关,但我正在关注此网页
编译一个简单的Java应用程序TestSetup.java
来调用第三方
工具:https://kunlei.github.io/cplex/cplex-java-setup。
解决方法
最下面的底线
以下Bash命令同时发送stdout
和stderr
javac
到屏幕和文件mk.out
:
javac -classpath /Some/NonExistent/Jar/File.jar TestSetup.java \
2>&1 | tee mk.out
如何找到
我发现问题主要出在使用Bash管道,
重定向和script
命令。后者负责
ANSI代码。我以前无法确定,因为我可以
无法在没有javac
的文件中捕获script
错误消息。所以
我首先解决了这个问题,然后将script
与
script
的缺失。这是我找到的。
以下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>&1
将stderr
定向到stdout
当前指向的位置,即
屏幕。然后,后续的>| mk.out
会引导stdout
(并且 only
std.out
至mk.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个引人入胜的页面供以后参考 相关的是:
- https://superuser.com/questions/380772/removing-ansi-color-codes-from-text-stream
- https://unix.stackexchange.com/questions/14684/removing-control-chars-including-console-codes-colours-from-script-output
- https://unix.stackexchange.com/questions/4527/program-that-passes-stdin-to-stdout-with-color-codes-stripped
提及由stdin
组成,但是您需要Ubuntu。