我从C#开始使用bash(cygwin),为此我从C:\\cygwin64\\bin\\bash.exe
创建了一个带有参数--login -i
的新进程。我也重定向了它的输出。
Bash运行,但输出包含意外字符,例如[0m[37;1m
或[0m>
或[K>
或甚至>
(在所有字符之前都有一个ESC
字符这些但stackoverflow似乎没有让它显示)。这是出乎意料的原因,因为我似乎没有从薄荷程序中看到任何这些角色。
为什么会这样?这些角色来自哪里?如何防止它们出现?
答案 0 :(得分:0)
意外字符是用于格式化文本输出的转义序列(关于终端仿真器)。 (有关详细信息,请参阅Wikipedia: terminal emulator。)
详细地,可以使用某些bash变量(即PS1, PS2, PS3, PS4)来配置提示的输出。在How to change bash prompt color based on exit code of last command?中,显示了修改它们的效果(仅用于娱乐)。
在你的情况下,bash
的调用应该提供一个特殊的脚本,它可以简单地重新定义它们而没有任何转义序列。因此,您可以摆脱不受欢迎的格式。这可能有所帮助:SO: Running a custom profile file on remote host但这似乎也很有希望:Is it possible to start a bash shell with a profile at a custom location, in a one liner command?。
写这篇文章,我记得某些命令(例如ls
)也支持彩色输出。因为我不确定我是否尝试过这个:
$ mkdir test ; cd test ; touch test1 ; ln -s test1 test2 ; mkdir test3 ; touch test4 ; chmod a+x test4
$ ls --color
test1 test2 test3 test4
$
我不知道如何用颜色格式化它,但是在我的xterm上,它看起来像Mardi Gras。因此,我使用hexdump
来显示效果:
$ ls --color | hexdump -c
0000000 t e s t 1 \n 033 [ 0 m 033 [ 0 1 ; 3
0000010 6 m t e s t 2 033 [ 0 m \n 033 [ 0 1
0000020 ; 3 4 m t e s t 3 033 [ 0 m \n 033 [
0000030 0 1 ; 3 2 m t e s t 4 033 [ 0 m \n
0000040
如您所见:ls
确实也使用终端转义序列。然后我想起了变量TERM
。此链接The TERM variable也提到terminfo
或termcap
,这些可能是游戏的一部分。
因此,除了重新定义PS1
... PS4
之外,重新定义TERM
也很有用:
$ TERM=
$ ls --color | hexdump -c
0000000 t e s t 1 \n t e s t 2 \n t e s t
0000010 3 \n t e s t 4 \n
0000018
$
顺便说一下。我认识到bash提示仍然是彩色的。思考两次这一点变得很明显:PS1
... PS4
中的转义序列是“硬编码的”,即不考虑TERM
的设置。
<强>更新强>
为了测试这个,我写了一个示例脚本mybashrc
:
PS1="> "
PS2=">>"
PS3=
PS4="++ "
TERM=
并在Windows 10(64位)上使用cygwin中的bash进行测试:
$ bash --init-file mybashrc -i
> echo "$PS1 $PS2 $PS3 $PS4"
> >> ++
> exit
exit
$
顺便说一下。我注意到[Backspace]键在我的示例会话中有点奇怪:它仍然具有预期的效果,但输出错误。输出为而不是删除最后一个字符,尽管内部缓冲区似乎正确处理了这个:
$ bash --init-file mybashrc -i
> echo "Ha ello"
Hello
> echo "Ha ello" | hexdump -c
0000000 H e l l o \n
0000006
> exit
exit
$
(在这两种情况下,我在echo "Ha
后输入[Backspace]一次。)原因可能是缺少终端仿真。
因此,我相信如果控制台(在您的应用程序中)适当地处理bash的输出通道中的退格,那么它应该不那么混乱。