可以使Terminal.app遵守ANSI转义码吗?

时间:2014-09-16 22:06:42

标签: macos terminal iterm2 ansi-escape

我注意到,TERM环境变量设置为xtermxterm-256color,Mac OS X的Terminal.app实用程序会考虑大多数ANSI转义码,至少当这些转义码属于改变文字颜色。

例如:

echo -e "\033[0;31mERROR:\033[0m It worked"

产地:

Screenshot

但是,我对ANSI转义码提供的游标位置操作功能更感兴趣。不幸的是, 类型的代码在Terminal.app中似乎不能很好地工作,从我能够收集到的。例如,我想要做的事情是这样的:

echo -e "\033[sHello world\033[uG'day"

ESC[s保存当前光标位置,而ESC[u恢复上次保存的位置。运行上面的脚本后,我希望“G' day”中的五个字符在光标重新定位后覆盖“Hello”的五个字符,产生以下内容:

G'day world

实际上,这正是我用iTerm2.app,ConEmu for Windows(运行MinGW或MSYS Git的bash.exe副本)等所得到的。然而,我在Terminal.app中看到的是:

Hello worldG'day

这是否有原因,除了Terminal.app之外,只是缺乏对这些代码的支持?有没有办法启用此功能?我有可能有错误配置的东西吗?我的TERM设置?还有别的吗?

我一直在各处搜索,但没有发现任何与Terminal.app相关的内容。我觉得很奇怪它会通过ANSI转义码支持彩色文本,但不会通过完全相同的技术重新定位光标。这似乎是一个相当明确的标准的相当随意的子集。这就是让我觉得我有一些错误配置的东西,而不是说Terminal.app是应该责备的......但是,我认为它可能根本无法完成。 (可能是iTerm2首先存在的原因之一?)

如果有人能够对这种情况有所了解,我们将不胜感激!

更新

所以,我做了更多的阅读和实验,发现了以下奇怪之处:<​​/ p>

在查看下面的n.m。的答案后,我决定将tput返回的字节写到文件中,看看它们与常规ANSI指令的区别。

$ echo "$(tput sc)Hello world$(tput rc)G'day" > out.bin
$ cat -e out.bin
^[7Hello world^[8G'day$

如果我发送序列为ESC 7ESC 8,则所有内容都会按预期运行,但如果我发送ESC { {1}}和[s ESC,据我所知,事物是ANSI SCP和RCP代码(分别保存光标位置和恢复光标位置)的更典型表示。由于在转义的八进制字节表示旁边放置ASCII十进制字符[u7是不可能的(8!= \0337),因此可以使用环境变量来避免依赖ESC

tput

我不确定为什么会这样。如果$ esc=$'\033' $ csi="${esc}[" $ echo "${csi}0;31mERROR:${csi}0m It worked." ERROR: It worked. # Color works, as before $ echo "${csi}sHello world${csi}uG'day" Hello worldG'day # No dice $ echo "${esc}7Hello world${esc}8G'day" G'day world # Success ESC7 ESC是ANSI SCP和RCP的某种专有或自定义代码,有可能从终端实施到终端实施不同,那么向我解释为什么8首先被创建。

不幸的是,我无法使用tput来处理我目前正在处理的事情,因为我不是专门在bash环境中工作。我更好奇的是如何从终端到终端解释原始字节,更具体地说,是否有一种方法可以让Terminal.app遵守所有其他的ANSI转义码终端模拟器我试过似乎没有问题。这可能吗?在这一点上,我开始认为它可能不是,这很好,但是确实很清楚,也可能知道原因。< / p>

1 个答案:

答案 0 :(得分:22)

不要使用ANSI代码。使用适当的基于terminfo的技术。未指定基于Xterm的终端支持所有ANSI代码。有些是为了兼容性,有些则不是。

保存光标位置序列由tput sc命令给出,恢复光标位置为tput rc

echo -e "$(tput sc)Hello world$(tput rc)G'day"

应该适用于支持这些序列的任何终端。

要查看支持序列的可读表示,请使用infocmp命令。输出可能很长。如果您对scrc感兴趣:

infocmp | grep --color ' [sr]c='

免责声明:在我的Linux机器上测试过,附近没有Mac。

<强>更新

在VT100终端之后建模xterm和xterm之后建模Terminal.app。 VT100未实现CSI uCSI s序列,但使用了DEC私有ESC 7ESC 8序列(source)。后来的VT模型支持CSI s/uESC 7/8,名称不同,功能略有不同(source)

ECMA 48似乎没有指定任何保存/恢复光标位置序列(source (PDF)),或者我在那里找不到它们。我不知道CSU s/u来自哪里。他们在VT510文档中的名字表明它们与SCO有某种联系。 This source表明它们实际上是没有标准含义的私人序列。 SUN终端使用SCI s进行重置。标记这两个序列ANSI可能是错误的。

现代版本的xterm和其他X11终端程序(konsole,rxvt ...)同时支持ESC 7/8CSI s/u,但terminfo数据库仅通告ESC 7/8。 Terminal.app显然只支持ESC 7/8