2010-09-24 50 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

你可以嘗試一些終端審訊轉義序列和超時的,如果沒有答覆。但是,那麼你可能不得不倒退,也許會問用戶他們使用的是什麼樣的終端。

相關問題