|
沙发

楼主 |
发表于 2009-3-9 01:47:59
|
只看该作者
确定终端类型
linux 里有一个 TERM 变量,它被设置为当前使用中的终端类型。它通常是在登录的时候由系统自动设置的。系统管理员可以为每一个直接与系统连接的终端设置一个默认终端类型,而远程、网络用户也许需要为之安排一个提示符让他们选择终端的类型。TERM 变量可以通过 telnet 进行协调,由 rlogin 功能传递。
使用以下命令可以查看自己正在使用的终端在系统的眼里到底是哪种类型:[root@localhost C]# echo $TERM
xterm 在上面的情况里,shell 是从一个名为 xterm 程序开始运行的,xterm 是一个 X 窗口系统下的终端仿真器。
terminfo 工具包里包含着一个拥有大量终端性能指标和转义字符这些信息构成的数据库,并且提供了统一的程序设计接口。有了这个工具包,程序设计工作得到极大的简化,并且能够随着数据库的扩展适应未来的终端,对不同类型的终端的支持不再需要由程序自己来提供。
terminfo 性能指标由“属性”来进行描述。这些“属性”被存储在一系列经过编译的 terminfo 文件里,一般被保存在 /usr/lib/terminfo 或者 /usr/share/terminfo 。对于每一个终端(也包括许多中打印机,它们也可以被定义在 terminfo 中),都有一个定义了性能指标和如何去访问这些特性的文件。避免创建一个非常大的目录,实际的文件被存放在子目录下面,子目录名简单的用终端类型的第一个字母来命名。因此,VT100型终端的定义就放在文件 ...terminfo/v/vt100 里。
对于每一种终端类型都对应有一个 terminfo 文件,文件格式为可读的源代码,然后用 tic 命令将其编译成一个更加紧凑(compact)有效的格式以方便应用程序使用。令人奇怪的是,X/Open 技术规范提到了源文件和编译格式的定义,但并没有提及从源代码转换为编译格式的 tic 命令。你可以使用 infocmp 程序打印出一个已编译 terminfo 条目的可读版本。
以下是对应于 VT100 终端的 terminfo 文件:[root@localhost ~]# infocmp vt100
# Reconstructed via infocmp from file: /usr/share/terminfo/v/vt100
vt100|vt100-am|dec vt100 (w/advanced video),
am, mc5i, msgr, xenl, xon,
cols#80, it#8, lines#24, vt#3,
acsc=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,
bel=^G, blink=\\E[5m$<2>, bold=\\E[1m$<2>,
clear=\\E[H\\E[J$<50>, cr=^M, csr=\\E[%i%p1%d;%p2%dr,
cub=\\E[%p1%dD, cub1=^H, cud=\\E[%p1%dB, cud1=^J,
cuf=\\E[%p1%dC, cuf1=\\E[C$<2>,
cup=\\E[%i%p1%d;%p2%dH$<5>, cuu=\\E[%p1%dA,
cuu1=\\E[A$<2>, ed=\\E[J$<50>, el=\\E[K$<3>, el1=\\E[1K$<3>,
enacs=\\E(B\\E)0, home=\\E[H, ht=^I, hts=\\EH, ind=^J, ka1=\\EOq,
ka3=\\EOs, kb2=\\EOr, kbs=^H, kc1=\\EOp, kc3=\\EOn, kcub1=\\EOD,
kcud1=\\EOB, kcuf1=\\EOC, kcuu1=\\EOA, kent=\\EOM, kf0=\\EOy,
kf1=\\EOP, kf10=\\EOx, kf2=\\EOQ, kf3=\\EOR, kf4=\\EOS, kf5=\\EOt,
kf6=\\EOu, kf7=\\EOv, kf8=\\EOl, kf9=\\EOw, lf1=pf1, lf2=pf2,
lf3=pf3, lf4=pf4, mc0=\\E[0i, mc4=\\E[4i, mc5=\\E[5i, rc=\\E8,
rev=\\E[7m$<2>, ri=\\EM$<5>, rmacs=^O, rmam=\\E[?7l,
rmkx=\\E[?1l\\E>, rmso=\\E[m$<2>, rmul=\\E[m$<2>,
rs2=\\E>\\E[?3l\\E[?4l\\E[?5l\\E[?7h\\E[?8h, sc=\\E7,
sgr=\\E[0%?%p1%p6%|%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;m%?%p9%t\\016%e\\017%;$<2>,
sgr0=\\E[m\\017$<2>, smacs=^N, smam=\\E[?7h, smkx=\\E[?1h\\E=,
smso=\\E[7m$<2>, smul=\\E[4m$<2>, tbc=\\E[3g, Xterm 终端 terminfo 定义:[root@localhost ~]# infocmp xterm
# Reconstructed via infocmp from file: /usr/share/terminfo/x/xterm
xterm|xterm terminal emulator (X Window System),
am, bce, km, mc5i, mir, msgr, npc, xenl,
colors#8, cols#80, it#8, lines#24, pairs#64,
acsc=``aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,
bel=^G, blink=\\E[5m, bold=\\E[1m, cbt=\\E[Z, civis=\\E[?25l,
clear=\\E[H\\E[2J, cnorm=\\E[?12l\\E[?25h, cr=^M,
csr=\\E[%i%p1%d;%p2%dr, cub=\\E[%p1%dD, cub1=^H,
cud=\\E[%p1%dB, cud1=^J, cuf=\\E[%p1%dC, cuf1=\\E[C,
cup=\\E[%i%p1%d;%p2%dH, cuu=\\E[%p1%dA, cuu1=\\E[A,
cvvis=\\E[?12;25h, dch=\\E[%p1%dP, dch1=\\E[P, dl=\\E[%p1%dM,
dl1=\\E[M, ech=\\E[%p1%dX, ed=\\E[J, el=\\E[K, el1=\\E[1K,
flash=\\E[?5h$<100/>\\E[?5l, home=\\E[H, hpa=\\E[%i%p1%dG,
ht=^I, hts=\\EH, ich=\\E[%p1%d@, il=\\E[%p1%dL, il1=\\E[L,
ind=^J, indn=\\E[%p1%dS, invis=\\E[8m,
is2=\\E[!p\\E[?3;4l\\E[4l\\E>, kDC=\\E[3;2~, kEND=\\E[1;2F,
kHOM=\\E[1;2H, kIC=\\E[2;2~, kLFT=\\E[1;2D, kNXT=\\E[6;2~,
kPRV=\\E[5;2~, kRIT=\\E[1;2C, kb2=\\EOE, kbs=\\177, kcbt=\\E[Z,
kcub1=\\EOD, kcud1=\\EOB, kcuf1=\\EOC, kcuu1=\\EOA,
kdch1=\\E[3~, kend=\\EOF, kent=\\EOM, kf1=\\EOP, kf10=\\E[21~,
kf11=\\E[23~, kf12=\\E[24~, kf13=\\EO2P, kf14=\\EO2Q,
kf15=\\EO2R, kf16=\\EO2S, kf17=\\E[15;2~, kf18=\\E[17;2~,
kf19=\\E[18;2~, kf2=\\EOQ, kf20=\\E[19;2~, kf21=\\E[20;2~,
kf22=\\E[21;2~, kf23=\\E[23;2~, kf24=\\E[24;2~, kf25=\\EO5P,
kf26=\\EO5Q, kf27=\\EO5R, kf28=\\EO5S, kf29=\\E[15;5~,
kf3=\\EOR, kf30=\\E[17;5~, kf31=\\E[18;5~, kf32=\\E[19;5~,
kf33=\\E[20;5~, kf34=\\E[21;5~, kf35=\\E[23;5~,
kf36=\\E[24;5~, kf37=\\EO6P, kf38=\\EO6Q, kf39=\\EO6R,
kf4=\\EOS, kf40=\\EO6S, kf41=\\E[15;6~, kf42=\\E[17;6~,
kf43=\\E[18;6~, kf44=\\E[19;6~, kf45=\\E[20;6~,
kf46=\\E[21;6~, kf47=\\E[23;6~, kf48=\\E[24;6~, kf49=\\EO3P,
kf5=\\E[15~, kf50=\\EO3Q, kf51=\\EO3R, kf52=\\EO3S,
kf53=\\E[15;3~, kf54=\\E[17;3~, kf55=\\E[18;3~,
kf56=\\E[19;3~, kf57=\\E[20;3~, kf58=\\E[21;3~,
kf59=\\E[23;3~, kf6=\\E[17~, kf60=\\E[24;3~, kf61=\\EO4P,
kf62=\\EO4Q, kf63=\\EO4R, kf7=\\E[18~, kf8=\\E[19~, kf9=\\E[20~,
khome=\\EOH, kich1=\\E[2~, kind=\\E[1;2B, kmous=\\E[M,
knp=\\E[6~, kpp=\\E[5~, kri=\\E[1;2A, mc0=\\E[i, mc4=\\E[4i,
mc5=\\E[5i, meml=\\El, memu=\\Em, op=\\E[39;49m, rc=\\E8,
rev=\\E[7m, ri=\\EM, rin=\\E[%p1%dT, rmacs=\\E(B, rmam=\\E[?7l,
rmcup=\\E[?1049l, rmir=\\E[4l, rmkx=\\E[?1l\\E>, rmso=\\E[27m,
rmul=\\E[24m, rs1=\\Ec, rs2=\\E[!p\\E[?3;4l\\E[4l\\E>, sc=\\E7,
setab=\\E[4%p1%dm, setaf=\\E[3%p1%dm,
setb=\\E[4%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m,
setf=\\E[3%?%p1%{1}%=%t4%e%p1%{3}%=%t6%e%p1%{4}%=%t1%e%p1%{6}%=%t3%e%p1%d%;m,
sgr=%?%p9%t\\E(0%e\\E(B%;\\E[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p7%t;8%;m,
sgr0=\\E(B\\E[m, smacs=\\E(0, smam=\\E[?7h, smcup=\\E[?1049h,
smir=\\E[4h, smkx=\\E[?1h\\E=, smso=\\E[7m, smul=\\E[4m,
tbc=\\E[3g, u6=\\E[%i%d;%dR, u7=\\E[6n, u8=\\E[?1;2c, u9=\\E[c,
vpa=\\E[%i%p1%dd, 每一个 terminfo 定义由3个类型的数据项组成。这三种数据项被成为“性能名”(capname),它们分别定义了一个终端的性能(capability)。
布尔型性能指标简单的指示了这个终端是否支持某种特定的功能。例如,如果某个终端支持 XON/XOFF 流控制,就能在上面的清单里看到布尔性能指标“xon”。
数字性能指标定义了一些关于尺寸长度的数字,比如 lines(屏幕上可以显示几行),cols(屏幕上可以显示出几列)。数字和性能指标名称之间是用一个#字号隔开的,如上面引用部分的粉红色高亮部分。
字符串性能指标稍微复杂一些。它们用来定义两种泾渭分明的性能:用来访问终端功能的输出字符串 和 用户按下特定按键(通常是功能键或数字小键盘(numberic keypad)上的特殊键)时终端接收到的输入字符串。有的字符串性能指标很简单,如 el,表示删除到这一行的末尾。在 xterm 终端上,转义字符序列需要这么做: Esc-[-K .在 terminfo 的源文代码格式里要写成 el=\\E[K .
说明一下 Esc-[-K 如在 xterm 终端中时,如以下输入:[root@localhost ~]# DDDDDDDDDDDDDDDDDDDDDDDDDDDDD 上面,家粗高亮的 D 代表光标所在的地方,这时在键盘上键入 Ctrl+K 组合键,那么就会删除其后的所有字符(直到行末尾):[root@localhost ~]# DDDDDDDDDD
特殊的按键也以类似的方法定义。例如,F1 功能键在 xterm 中对应的是发送转义序列 Esc-O-P. 这被定义成 kf1=\\EOP .
在转义序列需要一些参数时情况就会变得复杂一些。大多数终端可以移动光标到一个特定的行列位置。很明显,为每一个可能的光标位置定义不同的性能指标那是不现实(impractical)的,解决的办法是使用一个带有参数的通用性字符串。例如,VT100 终端会使用转义字符 Esc-[-<row>-;-<col>-H 把光标移动到指定位置。在 terminfo 源代码格式里,转义序列被写成相当复杂的格式:
cup=\\E[%i%p1%d;%p2%dH$<5> .
上面格式中各参数的意思是:
\\E : 发送 Escape 字符
[ : 发送 [ 字符
%i : 增加参数的值
%p1 : 把第一个参数放在堆栈中
%d : 以十进制数输出堆栈上的数字
; : 发送 ; 字符
%p2 : 把第二个参数放到堆栈上
%d : 以十进制数输出堆栈上的数字
H : 发送 H 字符
这看起来很复杂,但允许参数以固定的顺序使用,这和终端所期望的出现在最终转义序列里的次序并没有冲突。%i 可以增加参数的值,这也是必须的;因为标准光标开始地址被指定在屏幕左上角的(0,0)的位置处,但 VT100 的这个位置的地址为(1,1)。最后一个参数 $<5> 表示终端需要延迟 5 个字符输出的时间后才会处理光标的移动。
UNIX/Linux 系统预定义了许多终端的性能指标。如果需要增加一个新的终端,你可以在 terminfo 手册页里查找完整的性能指标列表。一个好的开始通常是,首先找到一个和你所要定义的新终端类似的一个终端,也就是这个新终端即将作为这个已存在终端的一个变异体,或者一次性的完成(work through)整个终端的定义工作,然后再根据需求再进一步进行修订。
对于 man 手册页以外的标准参考是资料是 O'Reilly 出版社出版的《Termcap 和 Terminfo》一书,其作者是 John Strang 以及 Linda Mui。 |
|