"cygwin" 终端下未处理的转义序列
Escape sequences unprocessed under the "cygwin" terminal
我有一个 Java 应用程序,它使用 ANSI escape sequences 来显示颜色、定位光标等。
它在普通 Unices 下运行良好,
以及 xterm
和 mintty
(在 Cygwin 中),
但我在 cygwin
终端下 运行 遇到问题(即 bash
从 cmd.exe
启动)。
正如您从屏幕截图中看到的那样:
转义序列被输出 "as is",没有处理。另一方面,我可以很容易地 运行 smth 像 echo -e '3[1;31mTest'
-- 彩色文本就在那里。
同时,如果我从 Midnight Commander 子 shell 启动完全相同的应用程序,应用程序生成的转义序列将被正确解释:
此外,如果我使用 SSH 登录我的 Windows 框(即用远程连接替换本地连接,但保留相同的 cygwin
终端),再次处理转义序列就好了。
看起来像是在创建某种子外壳时(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.
为了使应用程序在从 cmd.exe
(TERM=cygwin
) 启动时能够使用 ANSI 转义序列,应用程序 本身 需要与 cygwin1.dll
链接,或者其输出需要通过 另一个 过滤(例如:mc
或 ssh
子外壳)。
同一个C程序:
#include <stdio.h>
int main() {
const char esc = 0x1b;
printf("%c[31;91;1mHello, World!%c[0m\n", esc, esc);
return 0;
}
使用 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)
但显示垃圾
←[31;91;1mHello, World!←[0m
当使用 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)
另一种解决方案是使用 ConEmu 作为外部输出过滤器(bash.exe
运行 作为 ConEmu.exe
的直接子项)。这种方法不需要与 cygwin1.dll
链接,因为输出过滤由 ConEmu 本身执行。缺点是 ConEmu 对转义序列的支持是有限的(特别是,它不理解用于画线的 VT100 备用字符集 ).
我有一个 Java 应用程序,它使用 ANSI escape sequences 来显示颜色、定位光标等。
它在普通 Unices 下运行良好,
以及 xterm
和 mintty
(在 Cygwin 中),
但我在 cygwin
终端下 运行 遇到问题(即 bash
从 cmd.exe
启动)。
正如您从屏幕截图中看到的那样:
转义序列被输出 "as is",没有处理。另一方面,我可以很容易地 运行 smth 像 echo -e '3[1;31mTest'
-- 彩色文本就在那里。
同时,如果我从 Midnight Commander 子 shell 启动完全相同的应用程序,应用程序生成的转义序列将被正确解释:
此外,如果我使用 SSH 登录我的 Windows 框(即用远程连接替换本地连接,但保留相同的 cygwin
终端),再次处理转义序列就好了。
看起来像是在创建某种子外壳时(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.
为了使应用程序在从 cmd.exe
(TERM=cygwin
) 启动时能够使用 ANSI 转义序列,应用程序 本身 需要与 cygwin1.dll
链接,或者其输出需要通过 另一个 过滤(例如:mc
或 ssh
子外壳)。
同一个C程序:
#include <stdio.h>
int main() {
const char esc = 0x1b;
printf("%c[31;91;1mHello, World!%c[0m\n", esc, esc);
return 0;
}
使用 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)
但显示垃圾
←[31;91;1mHello, World!←[0m
当使用 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)
另一种解决方案是使用 ConEmu 作为外部输出过滤器(bash.exe
运行 作为 ConEmu.exe
的直接子项)。这种方法不需要与 cygwin1.dll
链接,因为输出过滤由 ConEmu 本身执行。缺点是 ConEmu 对转义序列的支持是有限的(特别是,它不理解用于画线的 VT100 备用字符集 ).