我注意到,TERM
环境变量设置为xterm
或xterm-256color
,Mac OS X的Terminal.app实用程序会考虑大多数ANSI转义码,至少当这些转义码属于改变文字颜色。
例如:
echo -e "\033[0;31mERROR:\033[0m It worked"
产地:
但是,我对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
7
和ESC
8
,则所有内容都会按预期运行,但如果我发送ESC
{ {1}}和[s
ESC
,据我所知,事物是ANSI SCP和RCP代码(分别保存光标位置和恢复光标位置)的更典型表示。由于在转义的八进制字节表示旁边放置ASCII十进制字符[u
或7
是不可能的(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
ESC
和7
ESC
是ANSI SCP和RCP的某种专有或自定义代码,有可能从终端实施到终端实施不同,那么向我解释为什么8
首先被创建。
不幸的是,我无法使用tput
来处理我目前正在处理的事情,因为我不是专门在bash环境中工作。我更好奇的是如何从终端到终端解释原始字节,更具体地说,是否有一种方法可以让Terminal.app遵守所有其他的ANSI转义码终端模拟器我试过似乎没有问题。这可能吗?在这一点上,我开始认为它可能不是,这很好,但是确实很清楚,也可能知道原因。< / p>
答案 0 :(得分:22)
不要使用ANSI代码。使用适当的基于terminfo的技术。未指定基于Xterm的终端支持所有ANSI代码。有些是为了兼容性,有些则不是。
保存光标位置序列由tput sc
命令给出,恢复光标位置为tput rc
。
echo -e "$(tput sc)Hello world$(tput rc)G'day"
应该适用于支持这些序列的任何终端。
要查看支持序列的可读表示,请使用infocmp
命令。输出可能很长。如果您对sc
和rc
感兴趣:
infocmp | grep --color ' [sr]c='
免责声明:在我的Linux机器上测试过,附近没有Mac。
<强>更新强>
在VT100终端之后建模xterm和xterm之后建模Terminal.app。 VT100未实现CSI u
和CSI s
序列,但使用了DEC私有ESC 7
和ESC 8
序列(source)。后来的VT模型支持CSI s/u
和ESC 7/8
,名称不同,功能略有不同(source)。
ECMA 48似乎没有指定任何保存/恢复光标位置序列(source (PDF)),或者我在那里找不到它们。我不知道CSU s/u
来自哪里。他们在VT510文档中的名字表明它们与SCO有某种联系。 This source表明它们实际上是没有标准含义的私人序列。 SUN终端使用SCI s
进行重置。标记这两个序列ANSI可能是错误的。
现代版本的xterm和其他X11终端程序(konsole,rxvt ...)同时支持ESC 7/8
和CSI s/u
,但terminfo数据库仅通告ESC 7/8
。 Terminal.app显然只支持ESC 7/8
。