【发布时间】:2014-11-10 19:37:21
【问题描述】:
我注意到,在将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 [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 是首先创建。
不幸的是,我无法将tput 用于我目前的工作,因为我并不是专门在 bash 环境中工作。我更好奇原始字节是如何在终端之间解释的,更具体地说,是否有办法让 Terminal.app 尊重与我所有其他终端模拟器相同的 ANSI 转义码'试过似乎没有问题。这可能吗?在这一点上,我开始认为它可能根本不可能,这很好,但很高兴知道肯定,并且可能还了解原因。
【问题讨论】:
-
我不在我的 iMac 上,但使用
printf而不是echo和/或/usr/bin/echo而不是 shell 的内置echo可能值得一试。 -
我没有
/usr/bin/echo,但我确实有/bin/echo,而且printf和"\033[sHello world\033[uG'day"都没有,不幸的是......但是,printf当我分别为 SCP 和 RCP 代码发送ESC7和ESC8而不是ESC[s和ESC[u时,echo起作用了。我根据这种行为更新了问题。 -
查看this answer 了解
ESC 7和ESC 8工作的原因。
标签: macos terminal iterm2 ansi-escape