我注意到,在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,适用于Windows的ConEmu(运行MinGW或MSYS Git的bash.exe副本)所获得的东西,但是,在Terminal.app中看到的是:
Hello worldG'day
除了Terminal.app表单根本不支持这些代码之外,还有其他原因吗?有没有启用此功能的方法?我是否有可能配置错误?我的TERM设置?还有吗
我到处都在搜索,但是没有找到与Terminal.app相关的任何内容。我觉得奇怪的是,它可以通过ANSI转义码支持彩色文本,但不能通过完全相同的技术来重新定位光标。这似乎是相当明确的标准的相当任意的子集。这就是让我认为我配置错误的原因,而不是应归咎于Terminal.app……但是,我想这很可能根本无法完成。 (可能是iTerm2首先存在的原因之一?)
如果有人可以阐明这种情况,将不胜感激!
更新
因此,我做了一些阅读和实验,发现了以下奇怪之处:
在查看了以下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
[s
和ESC
[u
则不会一切正常,据我了解,这是ANSI SCP和RCP代码的更典型表示形式(光标位置和恢复光标位置)。由于不可能将ASCII十进制字符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
8
是ANSI SCP和RCP的某种专有或自定义代码,并且可能在终端实现之间有所不同,那么它将向我解释为什么tput
首先创建。不幸的是,由于我不是专门在bash环境中工作,因此我无法使用
tput
进行当前工作。我对如何从终端到终端解释原始字节感到更好奇,更具体地说,是,是否有办法让Terminal.app遵守与我所拥有的所有其他终端仿真器相同的ANSI转义代码尝试似乎没有问题。那可能吗? 在这一点上,我开始认为它可能根本不是,这很好,但是一定要知道,也可能要学习原因。 最佳答案
不要使用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。
更新
Terminal.app在xterm之后建模,而xterm在VT100终端之后建模。 VT100没有实现
CSI u
和CSI s
序列,但是使用了DEC私有(private)ESC 7
和ESC 8
序列(source)。后来的VT模型以不同的名称和稍微不同的功能(source)支持CSI s/u
和ESC 7/8
。ECMA 48似乎没有指定任何保存/恢复光标位置序列(source (PDF)),或者我在那里找不到它们。我不知道
CSU s/u
来自哪里。它们在VT510文档中的名称表明它们与SCO有某种联系。 This source表明它们实际上是没有标准含义的私有(private)序列。 SUN终端使用SCI s
进行重置。将这两个序列标记为ANSI可能是错误的。xterm和其他X11终端程序(konsole,rxvt ...)的现代版本的确支持
ESC 7/8
和CSI s/u
,但是terminfo数据库仅宣传ESC 7/8
。 Terminal.app显然仅支持ESC 7/8
。关于macos - 是否可以使Terminal.app遵守ANSI转义码?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25879183/