我注意到,在TERM环境变量设置为xtermxterm-256color的情况下,Mac OS X的Terminal.app实用程序会使用大多数ANSI转义码,至少当这些转义码与更改文本颜色有关时。

例如:

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

产生:

macos - 是否可以使Terminal.app遵守ANSI转义码?-LMLPHP

但是,我对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 7ESC 8发送给它,一切似乎都按预期工作,但是如果我将其发送给ESC [sESC [u则不会一切正常,据我了解,这是ANSI SCP和RCP代码的更典型表示形式(光标位置和恢复光标位置)。由于不可能将ASCII十进制字符78放在转义的八进制字节表示形式之后(\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 7ESC 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命令。输出可能会很长。如果您对scrc感兴趣:
infocmp | grep --color ' [sr]c='

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

更新

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

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

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

关于macos - 是否可以使Terminal.app遵守ANSI转义码?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25879183/

10-16 21:26