Macos Terminal.app是否可以遵守ANSI转义码?
我注意到,当Macos Terminal.app是否可以遵守ANSI转义码?,macos,terminal,iterm2,ansi-escape,Macos,Terminal,Iterm2,Ansi Escape,我注意到,当TERM环境变量设置为xterm或xterm-256color时,Mac OS X的Terminal.app实用程序尊重大多数ANSI转义码,至少当这些转义码与更改文本颜色有关时是如此 例如: echo -e "\033[0;31mERROR:\033[0m It worked" 产生: 然而,我更感兴趣的是ANSI转义码提供的光标位置操纵功能。不幸的是,从我收集到的信息来看,这种类型的代码在Terminal.app中似乎工作得不太好。例如,我想做的事情如下: echo -e "
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缺少对这些代码的支持之外,还有什么原因吗?有没有办法启用此功能?我是否有可能配置错误?我的术语设置?还有什么原因?
我一直在到处搜索,但没有找到任何与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
和ESC
发送给它,就不会像我所理解的那样,这是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
不幸的是,我无法将
tput
用于我目前正在进行的工作,因为我不是专门在bash环境中工作。我更好奇的是原始字节是如何从一个终端到另一个终端进行解释的,更具体地说,是否有办法让terminal.app遵守相同的ANSI转义码我尝试过的所有其他终端仿真器似乎都没有问题。这可能吗?在这一点上,我开始认为它可能根本没有问题,这很好,但最好能肯定地知道,并可能了解原因。不要使用ANSI代码。使用适当的基于terminfo的技术。基于Xterm的terMINAL并没有指定为支持所有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 privateESC 7
和ESC 8
序列。后来的VT模型支持CSI u
和ESC 7/8
,使用不同的名称和sl完全不同的功能
ECMA 48似乎没有指定任何保存/恢复光标位置序列,或者我在那里找不到它们。我不知道CSU s/u
来自哪里。VT510文档中的名称表明它们与SCO有某种联系。表明它们实际上是没有标准意义的私有序列。SUN终端使用SCI s
重置。将这两个序列标记为ANSI可能是错误的
xterm和其他X11终端程序的现代版本(konsole、rxvt…)确实支持
ESC 7/8
和CSI s/u
,但terminfo数据库只宣传ESC 7/8
。Terminal.app显然只支持ESC 7/8
我不在iMac上,但可能值得尝试使用printf
而不是echo
和/或/usr/bin/echo
shell内置的echo
。我没有/usr/bin/echo
,但我有一个<