6

ISO/IEC 2022 定义了 C0 和 C1 控制代码。C0 集是ASCII、ISO-8859-1 和 UTF-8(例如0x00、、)之间熟悉的代码。0x1fESCCRLF

一些 VT100 终端仿真器(例如screen(1)PuTTY)也支持 C1 集。这些是和之间的值0x800x9f例如,0x84将光标向下移动一行)。

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

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

4

4 回答 4

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

以上是:

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 范围(因此它们在该范围内没有可打印的字符)。

于 2010-11-08T22:47:50.493 回答
1

实际上,PuTTY 似乎不支持 C1 控件。

测试此功能的常用方法是使用vttest,它提供用于分别更改输入和输出以使用 8 位控件的菜单条目。PuTTY 对每个菜单条目的完整性检查失败,如果检查被禁用,则结果确认 PuTTY 不支持这些控件。

于 2015-03-11T21:14:48.753 回答
0

我认为没有一种直接的方法可以查询终端是否支持它们。您可以尝试令人讨厌的 hacky 变通方法(例如打印它们然后查询光标位置),但我真的不推荐任何类似的方法。

我认为您可以无条件地过滤掉这些 C1 代码。Unicode 将 U+0080.. U+009F 范围声明为控制字符,我认为您不应该将它们用于任何不同的用途。

(注意:您使用了0x84光标向下的示例。实际上,它U+0084以终端使用的任何编码进行编码,例如0xC2 0x84UTF-8。)

于 2015-04-22T21:00:22.643 回答
0

100% 自动执行它充其量是具有挑战性的。许多,如果不是大多数,Unix 接口是智能的(xterms 和诸如此类),但你实际上不知道是否连接到ASR33或运行 MSDOS 的 PC。

在此处输入图像描述

如果没有回复,您可以尝试一些终端询问转义序列和超时。但随后您可能不得不退后一步,可能会询问用户他们使用的是哪种终端。

于 2015-04-22T21:21:06.750 回答