以编程方式检测终端支持的 ANSI 转义码

以编程方式检测终端支持的 ANSI 转义码

我正在研究使用 ANSI 代码的 shell 脚本,发现由于某种原因,根据您的终端/操作系统支持不同的转义代码。

在某些情况下,我意外地得到了未解析的垃圾转储,我假设这意味着我的终端(在 Mac OS 上)不支持所使用的转义代码,尽管在很多地方都读到了这些含义相同的内容:

27 = 033 = 0x1b = ^[ = \e

在搜索中我发现这个关于检测斜杠转义支持的问题

选定的答案嗅探$TERM要检测的值

case $TERM in
  (|color(|?))(([Ekx]|dt|(ai|n)x)term|rxvt|screen*)*)
    PS1=$'\e\]0;$GENERATED_WINDOW_TITLE\a'"$PS1"
esac

但我想知道这有多可靠。

是否有一种标准方法来检查转义码支持(主要针对 Bash),或者该脚本几乎是常规的?

  • 或者,我可以使用什么转义代码来“保证”最广泛的支持?
  • echo 扩展 -e 怎么样?
  • 在可移植性/可用性/分发方面的一般最佳实践是什么脚本那使用或参考控制代码?

这是也很好读对于任何其他正在寻找信息的人。

答案1

您有具体的操作吗?

这是一个使用的例子突出模式,在许多终端上都会给出强烈的可见结果:

tput smso; echo hello, world; tput rmso

tput工具使用环境变量的值$TERM来确定要输出的转义序列(如果有)。例如

TERM=xterm
( tput smso; echo hello, world; tput rmso ) | hexdump -C
00000000  1b 5b 37 6d 68 65 6c 6c  6f 2c 20 77 6f 72 6c 64  |.[7mhello, world|
00000010  0a 1b 5b 32 37 6d                                 |..[27m|

TERM=dumb
( tput smso; echo hello, world; tput rmso ) | hexdump -C
00000000  68 65 6c 6c 6f 2c 20 77  6f 72 6c 64 0a           |hello, world.|

有趣的特征对可以在以下位置找到man 5 terminfo,其中一些如下:

  • 突出:smsormso
  • 下划线:smulrmul
  • 眨眼(是的!):blink
  • 双宽:swidmrwidm
  • 撤销:rev
  • 全部取消:sgr0

如果您想编写粗体文本,但前提是终端能够理解它,那么这样的代码片段就可以工作

boldOn=$(tput smso)
boldOff=$(tput rmso)
# ...
printf "%s%s%s\n" "$boldOn" 'This message will be in bold, when available' "$boldOff"

答案2

实际上,可以询问 DEC 终端(及其克隆和仿真,包括 xterm)的功能;只是与个人转义序列支持(或其完整性)无关。 UNIX 通常不使用此功能,而是依赖于 termcap/terminfo 数据库(也记录了这些怪癖)。

作为参考,序列是 DA(“设备属性”,ANSI 标准)和 DECID(“识别终端”,DEC 私有)。

相关内容