macos - 可以让 Terminal.app 尊重 ANSI 转义码吗?

标签 macos terminal iterm2 ansi-escape

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

例如:

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

产生:

Screenshot

但是,我对 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 发送给它,似乎一切都按预期工作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是首先创建的。

不幸的是,我无法使用 tput对于我目前正在做的事情,因为我并不是专门在 bash 环境中工作。我更好奇原始字节是如何从终端解释到终端的,更具体地说,是否有办法让 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 uCSI s序列,但使用 DEC 私有(private) ESC 7ESC 8序列 (source) .后来的 VT 型号同时支持 CSI s/uESC 7/8 ,名称不同,功能略有不同(source) .

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/

相关文章:

macos - 如何运行 iPad 模拟器?

在 Mac OSX Lion 上使用 tempfile.mkdtemp() 时,Python 的 os.chdir() 和 os.getcwd() 不匹配

c++ - 有没有办法让vim在另一个终端窗口中运行 “make”命令?

console - 是否可以查看以前 iTerm2 session 的日志或历史记录?

macos - lrzsz 在 mac os x 上不起作用

在提示中获取未 merge 路径的 Git 快捷方式

c++ - boost 进程运行 su

ios - React Native ios 构建在 react-native run-ios 上失败

linux - 如何同时触发多个nohup脚本?

objective-c - 如何在 Cocoa Mac os 开发中使用菜单项使鼠标悬停在 NSControlSegment 上?