我能想到的唯一方法是使用 C1 请求并测试返回值:
$ echo `echo -en "\x9bc"`
^[[?1;2c
$ echo `echo -e "\x9b5n"`
^[[0n
$ echo `echo -e "\x9b6n"`
^[[39;1R
$ echo `echo -e "\x9b0x" `
^[[2;1;1;112;112;1;0x
以上是:
CSI c Primary DA; request Device Attributes
CSI 5 n DSR; Device Status Report
CSI 6 n CPR; Cursor Position Report
CSI 0 x DECREQTPARM; Request Terminal Parameters
ESR 维护的 terminfo/termcap ( link ) 在用户字符串 7 和 9 (user7/u7, user9/u9) 中有几个这样的请求:
# 用户能力解读
#
# System V Release 4 和 XPG4 terminfo 格式定义了十个字符串
# 应用程序使用的功能,....在这个文件中,我们使用
# 其中某些功能用于描述未涵盖的功能
# 通过术语信息。映射如下:
#
# u9终端查询字符串(相当于ANSI/ECMA-48 DA)
# u8终端回复说明
# u7 光标位置请求(相当于 VT100/ANSI/ECMA-48 DSR 6)
# u6 光标位置报告(相当于 ANSI/ECMA-48 CPR)
#
# 终端查询字符串应该引起一个应答响应
# 从终端。的常用值将是 ^E(在较旧的 ASCII
# 终端)或 \E[c(在较新的 VT100/ANSI/ECMA-48 兼容终端上)。
#
# 游标位置请求()字符串应该引出一个游标位置
# 报告。典型值(对于 VT100 终端)是 \E[6n。
#
# 终端回复描述 (u8) 必须包含一个预期的
# 回复字符串。该字符串可能包含以下类似 scanf(3)
# 转义:
#
# %c 接受任何字符
# %[...] 接受给定集合中的任意数量的字符
#
# 光标位置report()字符串必须包含两个scanf(3)-style
# %d 个格式元素。其中第一个必须对应于 Y 坐标
# 和第二个到 %d。如果字符串包含序列 %i,它是
# 作为指令在读取每个值后减少它(这是
# 杯子字符串的反义词)。典型的 CPR 值为
# \E[%i%d;%dR(在 VT100/ANSI/ECMA-48 兼容终端上)。
#
# 这些功能由 tac(1m) 使用,terminfo 操作检查器
#(与 ncurses 5.0 一起分发)。
例子:
$ echo `tput u7`
^[[39;1R
$ echo `tput u9`
^[[?1;2c
当然,如果你只是想防止显示损坏,你可以使用less
方法,让用户在显示/不显示控制字符之间切换( -r 和 -R 选项less
)。此外,如果您知道您的输出字符集,则 ISO-8859 字符集具有为控制代码保留的 C1 范围(因此它们在该范围内没有可打印的字符)。