我可以确定终端是否解释C1控制代码?

caf*_*caf 6 unix gnu-screen ncurses vt100 termcap

ISO/IEC 2022定义了C0和C1控制代码.在C0组之间是熟悉的代码0x000x1f在ASCII,ISO-8859-1和UTF-8(例如ESC,CR,LF).

一些VT100终端仿真器(例如screen(1),PuTTY)也支持C1集.这些值之间0x800x9f(因此,例如,0x84向下移动光标的线).

我正在显示用户提供的输入.我不希望用户输入能够改变终端状态(例如移动光标).我目前正在过滤出C0集中的字符代码; 但是我想有条件地过滤出C1集,如果终端将它们解释为控制码.

有没有办法从数据库中获取此信息termcap

nin*_*alj 3

我能想到的唯一方法是使用 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
Run Code Online (Sandbox Code Playgroud)

以上是:

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
Run Code Online (Sandbox Code Playgroud)

ESR 维护的 terminfo/termcap ( link ) 在用户字符串 7 和 9 (user7/u7, user9/u9) 中有几个这样的请求:

# 用户能力的解释
#
# System V Release 4 和 XPG4 terminfo 格式定义了十个字符串
# 应用程序使用的功能,...在此文件中,我们使用
# 其中某些功能用于描述未涵盖的功能
# 由 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 兼容终端上)。
#
# 光标位置 request() 字符串应该引出光标位置
# 报告。典型值(对于 VT100 终端)为 \E[6n。
#
# 终端应答描述 (u8) 必须包含预期的
# 应答字符串。该字符串可能包含以下类似 scanf(3) 的内容
# 转义:
#
# %c 接受任意字符
# %[...] 接受给定集合中任意数量的字符
#
# 光标位置report()字符串必须包含两个scanf(3)-style
# %d 格式元素。其中第一个必须对应于 Y 坐标
# 第二个到%d。如果字符串包含序列%i,则为
# 作为读取每个值后递减每个值的指令(这是
# 与 cup 字符串相反的意义)。典型的 CPR 值是
# \E[%i%d;%dR(在 VT100/ANSI/ECMA-48 兼容终端上)。
#
# 这些功能由 terminfo 操作检查器 tac(1m) 使用
#(随 ncurses 5.0 一起分发)。

例子:

$ echo `tput u7`
^[[39;1R
$ echo `tput u9`
^[[?1;2c
Run Code Online (Sandbox Code Playgroud)

当然,如果您只想防止显示损坏,您可以使用less方法,让用户在显示/不显示控制字符之间切换(参考资料中的-r和-R选项less)。另外,如果您知道输出字符集,ISO-8859 字符集为控制代码保留了 C1 范围(因此它们在该范围内没有可打印字符)。