从C#开始的bash进程返回意外字符

时间:2017-04-20 09:38:45

标签: c# bash cygwin io-redirection mintty

我从C#开始使用bash(cygwin),为此我从C:\\cygwin64\\bin\\bash.exe创建了一个带有参数--login -i的新进程。我也重定向了它的输出。

Bash运行,但输出包含意外字符,例如[0m[37;1m[0m>[K>或甚至>(在所有字符之前都有一个ESC字符这些但stackoverflow似乎没有让它显示)。这是出乎意料的原因,因为我似乎没有从薄荷程序中看到任何这些角色。

为什么会这样?这些角色来自哪里?如何防止它们出现?

1 个答案:

答案 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也提到terminfotermcap,这些可能是游戏的一部分。

因此,除了重新定义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的输出通道中的退格,那么它应该不那么混乱。