2010-09-24 71 views
6

ISO/IEC 2022定义了the C0 and C1 control codes。在C0集是0x000x1f之间熟悉的代码在ASCII,ISO-8859-1和UTF-8(例如ESCCRLF)。我可以确定终端是否解释C1控制代码?

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

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

有没有从数据库中获取此信息的方法,如termcap

回答

2

做到这一点,我能想到的是使用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 

是terminfo/termcap的是ESR (link)在用户字符串7和9(用户7/u7,用户9/u9)中有几个请求:

 
# INTERPRETATION OF USER CAPABILITIES 
# 
# The System V Release 4 and XPG4 terminfo format defines ten string 
# capabilities for use by applications, .... In this file, we use 
# certain of these capabilities to describe functions which are not covered 
# by terminfo. The mapping is as follows: 
# 
#  u9  terminal enquire string (equiv. to ANSI/ECMA-48 DA) 
#  u8  terminal answerback description 
#  u7  cursor position request (equiv. to VT100/ANSI/ECMA-48 DSR 6) 
#  u6  cursor position report (equiv. to ANSI/ECMA-48 CPR) 
# 
# The terminal enquire string should elicit an answerback response 
# from the terminal. Common values for will be ^E (on older ASCII 
# terminals) or \E[c (on newer VT100/ANSI/ECMA-48-compatible terminals). 
# 
# The cursor position request() string should elicit a cursor position 
# report. A typical value (for VT100 terminals) is \E[6n. 
# 
# The terminal answerback description (u8) must consist of an expected 
# answerback string. The string may contain the following scanf(3)-like 
# escapes: 
# 
#  %c  Accept any character 
#  %[...] Accept any number of characters in the given set 
# 
# The cursor position report() string must contain two scanf(3)-style 
# %d format elements. The first of these must correspond to the Y coordinate 
# and the second to the %d. If the string contains the sequence %i, it is 
# taken as an instruction to decrement each value after reading it (this is 
# the inverse sense from the cup string). The typical CPR value is 
# \E[%i%d;%dR (on VT100/ANSI/ECMA-48-compatible terminals). 
# 
# These capabilities are used by tac(1m), the terminfo action checker 
# (distributed with ncurses 5.0). 

实施例:

$ echo `tput u7` 
^[[39;1R 
$ echo `tput u9` 
^[[?1;2c 

当然,如果仅要防止显示腐败,可以使用less方法,并且让显示/不显示控制字符之间(-r和用户交换机-R选项在less)。另外,如果你知道你的输出字符集,ISO-8859字符集有控制码保留的C1范围(所以它们在该范围内没有可打印的字符)。

1

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

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

-1

我不认为有一种直接的方式来查询终端是否支持它们。你可以尝试讨厌的哈克变通办法(像打印它们,然后查询光标位置),但我真的不推荐沿着这些线。

我想你可以无条件地过滤掉这些C1代码。 Unicode将U + 0080 .. U + 009F范围声明为控制字符,我认为你不应该将它们用于任何不同的事物。 (注意:您使用0x84作为光标向下的示例,实际上U+0084以终端使用的编码编码,例如用于UTF-8的0xC2 0x84编码。)

0

自动做100%充满挑战。很多(如果不是大多数)Unix界面很聪明(xterms和whatnot),但实际上并不知道是否连接到ASR33或运行MSDOS的PC。

enter image description here

你可以尝试一些终端审讯转义序列和超时的,如果没有答复。但是,那么你可能不得不倒退,也许会问用户他们使用的是什么样的终端。

相关问题