在“cygwin”终端下未处理的转义序列

Bas*_*ass 1 java windows cygwin ansi-escape

我有一个 Java 应用程序,它使用ANSI 转义序列来显示颜色、定位光标等。

它在常规 Unices 下xterm以及在和mintty(在Cygwin 中)下都可以正常工作,但是我在cygwin终端下运行它时遇到了问题(即bash从 启动cmd.exe)。

正如您从屏幕截图中看到的:

在此处输入图片说明

转义序列“按原样”输出,无需处理。另一方面,我可以轻松地运行 smth 之类的echo -e '\033[1;31mTest'- 并且彩色文本就在那里。

同时,如果我从Midnight Commander子shell启动完全相同的应用程序,应用程序生成的转义序列将被正确解释:

在此处输入图片说明

此外,如果我使用 SSH 登录到我的 Windows 机器(即用远程连接替换本地连接,但保留相同的cygwin终端),同样,转义序列处理得很好。

看起来当创建某种类型的子外壳(mcssh)时,终端会被置于其他模式。但是玩与stty没有帮助,也没有 export'ing TERM=ansi

任何人都可以请提出任何解决方案吗?

我在跑

CYGWIN_NT-6.3 UNIT-725 2.5.1(0.297/5/3) 2016-04-21 22:14 x86_64 Cygwin
Run Code Online (Sandbox Code Playgroud)

和 Windows 8.1。

Bas*_*ass 5

为了使应用程序能够在从cmd.exe( TERM=cygwin)启动时使用 ANSI 转义序列,应用程序本身需要与 链接cygwin1.dll,或者其输出需要通过另一个(例如:mcssh子shell)进行过滤。

相同的C程序:

#include <stdio.h>

int main() {
    const char esc = 0x1b;
    printf("%c[31;91;1mHello, World!%c[0m\n", esc, esc);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

使用Cygwin GCC编译时支持颜色输出:

$ ldd test-ansi-escape.exe
    ntdll.dll => /cygdrive/c/Windows/SYSTEM32/ntdll.dll (0x7ffeeb450000)
    KERNEL32.DLL => /cygdrive/c/Windows/system32/KERNEL32.DLL (0x7ffee92c0000)
    KERNELBASE.dll => /cygdrive/c/Windows/system32/KERNELBASE.dll (0x7ffee8700000)
    cygwin1.dll => /usr/bin/cygwin1.dll (0x180040000)
Run Code Online (Sandbox Code Playgroud)

但显示垃圾像

?[31;91;1mHello, World!?[0m
Run Code Online (Sandbox Code Playgroud)

使用MSVC编译时或mingw64-x86_64-gcc

$ ldd test-ansi-escape.exe
    ntdll.dll => /cygdrive/c/Windows/SYSTEM32/ntdll.dll (0x7ffeeb450000)
    ntdll.dll => /cygdrive/c/Windows/SYSTEM32/ntdll.dll (0x770a0000)
    wow64.dll => /cygdrive/c/Windows/SYSTEM32/wow64.dll (0x76fd0000)
    wow64win.dll => /cygdrive/c/Windows/system32/wow64win.dll (0x77020000)
    wow64cpu.dll => /cygdrive/c/Windows/system32/wow64cpu.dll (0x77090000)
    ??? => ??? (0x1040000)
    KERNEL32.DLL => /cygdrive/c/Windows/SYSTEM32/KERNEL32.DLL (0x76480000)
    ??? => ??? (0x1040000)
    ??? => ??? (0x1040000)
    KERNEL32.DLL => /cygdrive/c/Windows/SYSTEM32/KERNEL32.DLL (0x76480000)
    KERNELBASE.dll => /cygdrive/c/Windows/SYSTEM32/KERNELBASE.dll (0x74b40000)
    MSVCR120D.dll => /cygdrive/c/Windows/SYSTEM32/MSVCR120D.dll (0x62b90000)
Run Code Online (Sandbox Code Playgroud)

另一种解决方案是使用ConEmu作为外部输出过滤器(bash.exe作为 的直接子级运行ConEmu.exe)。这种方法不需要与 链接cygwin1.dll,因为输出过滤是由ConEmu本身执行的。缺点是ConEmu对转义序列的支持是有限的(特别是,它不理解用于线条绘制的VT100 替代字符集)。