首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >可以使Terminal.app遵守ANSI转义码吗?

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

Stack Overflow用户
提问于 2014-09-16 22:06:42
回答 1查看 11.4K关注 0票数 27

我注意到,当TERM环境变量设置为xtermxterm-256color时,Mac的Terminal.app实用程序尊重大多数ANSI转义代码,至少当这些转义代码涉及更改文本颜色时。

例如:

代码语言:javascript
复制
echo -e "\033[0;31mERROR:\033[0m It worked"

生产:

但是,我更感兴趣的是ANSI转义代码提供的游标位置操作功能。不幸的是,从我所收集到的数据来看,这种类型的代码在Terminal.app中似乎工作得不太好。例如,我想做的是这样的事情:

代码语言:javascript
复制
echo -e "\033[sHello world\033[uG'day"

ESC[s保存当前光标位置,而ESC[u恢复上次保存的位置。由于运行了上面的脚本,我希望在重新定位光标之后,“G‘’day”中的五个字符会覆盖“Hello”的五个字符,从而产生以下结果:

代码语言:javascript
复制
G'day world

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

代码语言:javascript
复制
Hello worldG'day

,除了Terminal.app没有对这些代码的支持之外,还有其他原因吗?有什么方法可以启用此功能吗?我有可能有什么东西配置不当吗?我的学期安排?还有什么吗?

我一直在到处搜索,但是没有发现任何与Terminal.app相关的东西,特别是。我觉得奇怪的是,它会通过ANSI转义代码支持彩色文本,但不会通过完全相同的技术重新定位光标。这似乎是定义良好的标准的一个相当任意的子集。这让我觉得我做错了什么,而不是Terminal.app是…的罪魁祸首但是,我想这是有可能的,它只是不能做到。(可能是iTerm2存在的原因之一吗?)

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

更新

因此,我做了更多的阅读和实验,并发现了以下奇怪之处:

在查看了N.M.下面的答案之后,我决定将tput返回的字节写到一个文件中,看看它们与常规的ANSI指令有何不同。

代码语言:javascript
复制
$ 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代码的更典型的表示形式(分别保存光标位置和恢复光标位置)。由于在转义八进制字节表示旁边放置78十进制字符是不可能的(\0337 != ESC),所以可以使用环境变量来避免依赖tput

代码语言:javascript
复制
$ 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

不幸的是,我无法使用tput来完成我目前正在做的工作,因为我并不是只在bash环境中工作。我更好奇的是,原始字节是如何从一个终端解释到另一个终端的,更具体地说,是--是否有一种方法可以让Terminal.app尊重我尝试过的所有其他终端模拟器似乎都没有问题的相同的ANSI转义代码。这有可能吗?,现在,我开始认为它可能不是,这是很好的,但很高兴知道,并可能了解原因。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-09-16 22:46:24

不要使用ANSI密码。使用正确的基于终端的技术。没有指定基于Xterm的终端来支持所有ANSI代码.有些是为了兼容性,有些则不是。

保存游标位置序列由tput sc命令提供,恢复游标位置为tput rc

代码语言:javascript
复制
echo -e "$(tput sc)Hello world$(tput rc)G'day"

应该在任何支持这些序列的终端上工作。

若要查看所支持序列的可读性表示形式,请使用infocmp命令。输出可能相当长。如果你对scrc感兴趣

代码语言:javascript
复制
infocmp | grep --color ' [sr]c='

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

更新

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

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

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

票数 27
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25879183

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档