我有一个Java应用程序,它使用ANSI escape sequences来显示颜色,定位光标等等。
在常规Unices下工作正常,
以及xterm
和mintty
(在 Cygwin 中),
但我在cygwin
终端(即从bash
发起的cmd.exe
)运行它时遇到问题。
从屏幕截图中可以看出:
转义序列按原样输出"没有处理。另一方面,我可以像echo -e '\033[1;31mTest'
一样轻松运行smth - 颜色文本就在那里。
同时,如果我从Midnight Commander子shell启动完全相同的应用程序,则应用程序生成的转义序列将被正确解释:
另外,如果我使用SSH登录我的Windows框(即替换远程的本地连接,但保留相同的cygwin
终端),再次处理转义序列就好了。
看起来当创建某种子shell(mc
或ssh
)时,终端会进入其他模式。但是使用stty
并没有帮助,也没有导出TERM=ansi
。
有人可以建议任何解决方案吗?
我正在跑步
CYGWIN_NT-6.3 UNIT-725 2.5.1(0.297/5/3) 2016-04-21 22:14 x86_64 Cygwin
和Windows 8.1。
答案 0 :(得分:2)
为了使应用程序在从cmd.exe
(TERM=cygwin
)启动时能够使用ANSI转义序列,应用程序本身需要与{{{ 1}},或者其输出需要通过另一个进行过滤,这是(例如:cygwin1.dll
或mc
个子shell。
相同的 C 计划:
ssh
使用 Cygwin GCC 编译时支持颜色输出:
#include <stdio.h>
int main() {
const char esc = 0x1b;
printf("%c[31;91;1mHello, World!%c[0m\n", esc, esc);
return 0;
}
但显示像
这样的垃圾$ 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)
使用 MSVC 或←[31;91;1mHello, World!←[0m
编译时
mingw64-x86_64-gcc
另一种解决方案是使用ConEmu作为外部输出过滤器($ 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)
作为bash.exe
的直接子项运行)。此方法不需要与ConEmu.exe
链接,因为输出过滤由 ConEmu 本身执行。缺点是 ConEmu 对转义序列的支持是有限的(特别是,它不理解用于线条绘制的 VT100备用字符集)。