如果终端仿真器和其中运行的 Shell 使用不同的术语类型,可能会发生什么“坏”事情(以及为什么)?

如果终端仿真器和其中运行的 Shell 使用不同的术语类型,可能会发生什么“坏”事情(以及为什么)?

例如,在 PuTTY 的配置中,我将终端类型设置为,但在 SSH 登录后,我在 shell 中xterm-256color更改了它。export TERM=linux

我知道它在大多数情况下都运作良好。只是想从技术角度了解不一致(PuTTY 和远程 Shell 之间)实际上意味着什么。

答案1

TERM变量用于查找终端/模拟器的功能以及为终端控制功能发送的正确代码,例如更改颜色、移动光标或清除屏幕。

理论上,该TERM变量所标识的终端类型将由位于/usr/share/terminfo/目录树中的终端类型描述准确地描述。实际上,终端仿真器可能存在错误,导致其行为偏离类型规范。

(终端类型规范本身也可能包含错误,但这是非常古老的技术,大多数错误很久以前就被解决了。)

打个比方,终端将使用自己的母语进行交流;应用程序通常不会直接说出它,而是使用术语信息数据库作为一组词典/短语手册与终端进行通信。 TERM 环境变量将决定使用哪个词典/短语手册。

如果 TERM 值只是稍微错误,即指示终端类型不完全正确但足够相似,那么事情可能大部分正常,也许只是减少了功能,例如只有 16 种颜色而不是 256 种颜色,正如 berndbausch 在问题评论中所说。

如果程序尝试使用实际终端类型中不存在的功能,您可能会在屏幕上看到一些垃圾字符。如果错误是相反的(即终端类型描述不包括您的终端实际具有的功能),那么程序将表现得好像您的终端没有该功能可用。

但是,如果 TERM 值完全错误(指示完全不相关的终端类型),则清除屏幕和其他基本功能之类的操作将不可用,并且任何使用它们的尝试很可能会在屏幕上产生垃圾字符,因为程序以终端仿真器实际上无法识别的格式发送终端控制代码。在这种状态下,使用普通文本编辑器(而不是传统的面向行的编辑器,如经典exed)将非常困难或不可能,直到 TERM 值被更正为止。

如果 TERM 值完全缺失,大多数需要它的程序将采用默认值dumb:一个非常古老的终端,其功能极其有限,甚至可能有打印机而不是屏幕。在这种情况下,您不会得到垃圾字符,但就像完全不正确的术语设置一样,使用常规文本编辑器或任何产生基于文本的全屏显示(下拉或弹出菜单)例如,在现有视图之上)在终端窗口上将是不可能的。

有关使用非常旧的终端的示例,请参阅 YouTube 上 CuriousMarc 的视频: https://youtu.be/2XLZ4Z8LpEE?t=501

请注意,在视频中,tty33Linux 中实际上有一个可用的特定 TERM 值,尽管 CuriousMarc 已agetty为他设置了该值,而不是直接分配该TERM变量。其dumb价值可能比这更简单!

由于此 TERM 类型的内容旨在涵盖许多旧技术,这些技术不一定具有可用作类型检测机制的任何内容,因此最初根本没有终端类型自动检测的规定。

getty对于硬连线串行终端,系统管理员在为连接到新终端的每个串行端口添加进程时应该配置正确的终端类型。对于调制解调器线路,系统可能配置为询问用户对于正确的终端类型,请输入 in/etc/profile或类似的内容,除非检测到会话是非交互式会话。

终端类型自动检测有一些进展,但这些进展并不适用于所有情况(因为有太多不同的旧终端类型),因此自动检测仍然是一个可选功能,如果管理员认为需要,可以启用它。对他们来说这是值得的。

后来,当开发基于网络协议的远程访问方法时,添加的功能之一是能够在连接时自动将一些额外信息从客户端传递到远程主机,TERM 值可能是其中的第一个。 “大家都很高兴。”

答案2

PuTTY 仅使用“终端类型”配置选项作为默认TERM环境变量PuTTY ssh 客户端什么时候请求远程服务器上的伪终端

使用该设置来确定终端序列PuTTY 终端仿真器识别并解释它们的方式将是相当愚蠢的——事实上,PuTTY 是不做这样的事

答案3

实际上,虽然 PuTTY 的行为是相似的对于编写这些描述的终端来说,它既不是超集,也不是两者的精确匹配。

当终端描述与终端不匹配时,会出现一些问题:

  • 如果它列出了终端以不同方式实现的功能,那么应用程序将表现不正确
  • 如果它省略了终端实现的功能,应用程序将忽略该功能
  • 如果它列出了终端未实现的功能,那么应用程序将再次出现错误行为。

PuTTY 的推荐终端描述是“油灰”“腻子-256色”。使用 infocmp 显示差异可以说明:

  • 一般来说,支持256色的终端也支持8色。每个组内都存在差异。 PuTTY 缺乏自定义调色板的能力(因此它的 256 色支持不完整),但它确实部分支持该功能:
    将 putty 与 putty-256color 进行比较。
        比较布尔值。
        抄送:T:F。
        比较数字。
        颜色:8、256。
        对:64、65536。
        比较字符串。
        initc: '\E]P%p1%x%p2%{255}%*%{1000}%/%02x%p3%{255}%*%{1000}%/%02x%p4%{255}% *%{1000}%/%02x',NULL。
        setab: '\E[4%p1%dm', '\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8 }%-%d%e48;5;%p1%d%;m'.
        setaf: '\E[3%p1%dm', '\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8 }%-%d%e38;5;%p1%d%;m'.

比较“腻子”操作系统表明每个都有另一个缺乏的功能,并且对于共同功能有些是不同的:

将 Putty 与 Linux 进行比较。
    比较布尔值。
    黑白:T:F。
    欧:F:T。
    小时:时间:F。
    斧头:F:T。
    XT:T:F。
    比较数字。
    NCV:22、18。
    比较字符串。
    acsc: '``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~', '++\,\,--..00``aaffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~'。
    cbt: '\E[Z', NULL。
    civis: '\E[?25l', '\E[?25l\E[?1c'.
    cnorm: '\E[?25h', '\E[?25h\E[?0c'。
    cud1: '\ED', '\n'。
    cuu1: '\EM', '\E[A'。
    cvvis: NULL, '\E[?25h\E[?8c'。
    暗淡:NULL,'\E[2m'。
    显示: '%?%p1%{8}%=%t\E%%G\342\227\230\E%%@%e%p1%{10}%=%t\E%%G\342 \227\231\E%%@%e%p1%{12}%=%t\E%%G\342\231\0\E%%@%e%p1%{13}%=%t\ E%%G\342\231\252\E%%@%e%p1%{14}%=%t\E%%G\342\231\253\E%%@%e%p1%{15 }%=%t\E%%G\342\230\274\E%%@%e%p1%{27}%=%t\E%%G\342\206\220\E%%@% e%p1%{155}%=%t\E%%G\340\202\242\E%%@%e%p1%c%;',NULL。
    dsl: '\E]0;\007', NULL。
    enacs: '\E(B\E)0', '\E)0'。
    闪烁:'\E[?5h$<100/>\E[?5l', '\E[?5h$\E[?5l'。
    fsl:'^G',NULL。
    ich: NULL, '\E[%p1%d@'。
    ich1: NULL, '\E[@'。
    indn: '\E[%p1%dS', NULL。
    is2: '\E7\E[r\E[m\E[?7h\E[?1;4;6l\E[4l\E8\E>\E]R', NULL。
    ka1: '\EOq', NULL。
    ka3: '\EOs', NULL。
    kb2: '\EOr', '\E[G'.
    kc1: '\EOp', NULL。
    kc3: '\EOn', NULL。
    kcub1: '\EOD', '\E[D'.
    kcud1: '\EOB', '\E[B'.
    kcuf1: '\EOC', '\E[C'.
    kcuu1: '\EOA', '\E[A'.
    肯特:'\EOM',NULL。
    kf0: '\EOy', NULL。
    kf1: '\E[11~', '\E[[A'.
    kf2: '\E[12~', '\E[[B'.
    kf3: '\E[13~', '\E[[C'.
    kf4: '\E[14~', '\E[[D'.
    kf5: '\E[15~', '\E[[E'.
    种类:'\E[B',NULL。
    kmous: '\E[', NULL。
    rs1: NULL, '\Ec\E]R'。
    rs2: '\E<\E["p\E[50;6"p\Ec\E[?3l\E]R\E[?1000l', NULL。
    s0ds: '\E[10m', NULL。
    s1ds: '\E[11m', NULL。
    s2ds: '\E[12m', NULL。
    sgr: '\E[0%?%p1%p6%|%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4% t;5%;m%?%p9%t\016%e\017%;', '\E[0;10%?%p1%t;7%;%?%p2%t;4%;% ?%p3%t;7%;%?%p4%t;5%;%?%p5%t;2%;%?%p6%t;1%;m%?%p9%t\016%e \017%;'。
    smcup: '\E[?47h', NULL。
    smkx: '\E[?1h\E=', NULL。
    tsl: '\E]0;', NULL。
    TS: '\E]0;', NULL。
    XM: '\E[?1006;1000%?%p1%{1}%=%th%el%;', NULL。
    kp1: '\EOq', NULL。
    kp2: '\EOr', NULL。
    kp3: '\EOs', NULL。
    kp4: '\EOt', NULL。
    kp5: '\EOu', NULL。
    kp6: '\EOv', NULL。
    kp7: '\EOw', NULL。
    kp8: '\EOx', NULL。
    kp9: '\EOy', NULL。
    kpADD:'\EOl',NULL。
    kpDIV:'\EOQ',NULL。
    kpDOT: '\EOn', NULL。
    kpMUL:'\EOR',NULL。
    kpNUM:'\EOP',NULL。
    kpSUB: '\EOS', NULL。
    kpZRO: '\EOp', NULL。
    xm: '\E[<%i%p3%d;%p1%d;%p2%d;%?%p4%tM%em%;', NULL。

比较“putty-256color”和xterm-256color表明 PuTTY 没有(例如)实现 xterm 提供的大多数功能键组合:

将 putty-256color 与 xterm-256color 进行比较。
    比较布尔值。
    OTbs:F:T。
    黑白:T:F。
    ccc:F:T。
    小时:时间:F。
    公里: F:T。
    mc5i:F:T。
    NPC:F:T。
    克森:T:F。
    斧头:F:T。
    比较数字。
    列数:NULL,80。
    行:NULL,24。
    NCV:22,空。
    U8:1,空。
    比较字符串。
    acsc:“aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~”,“aaffggiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~”。
    清除:'\E[H\E[J','\E[H\E[2J'。
    cnorm: '\E[?25h', '\E[?12l\E[?25h'.
    cud1: '\ED', '\n'。
    cuu1: '\EM', '\E[A'。
    cvvis: NULL, '\E[?12;25h'。
    暗淡:NULL,'\E[2m'。
    显示: '%?%p1%{8}%=%t\E%%G\342\227\230\E%%@%e%p1%{10}%=%t\E%%G\342 \227\231\E%%@%e%p1%{12}%=%t\E%%G\342\231\0\E%%@%e%p1%{13}%=%t\ E%%G\342\231\252\E%%@%e%p1%{14}%=%t\E%%G\342\231\253\E%%@%e%p1%{15 }%=%t\E%%G\342\230\274\E%%@%e%p1%{27}%=%t\E%%G\342\206\220\E%%@% e%p1%{155}%=%t\E%%G\340\202\242\E%%@%e%p1%c%;',NULL。
    dsl: '\E]0;\007', NULL。
    enacs: '\E(B\E)0', NULL。
    fsl:'^G',NULL。
    ich: NULL, '\E[%p1%d@'。
    initc: NULL, '\E]4;%p1%d;rgb\:%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/ %2.2X/%p4%{255}%*%{1000}%/%2.2X\E\\'。
    invis: NULL, '\E[8m'。
    is2: '\E7\E[r\E[m\E[?7h\E[?1;4;6l\E[4l\E8\E>\E]R', '\E[!p\E [?3;4l\E[4l\E>'。
    kDC: NULL, '\E[3;2~'。
    kEND: NULL, '\E[1;2F'。
    kHOM:NULL,'\E[1;2H'。
    kIC: NULL, '\E[2;2~'。
    kLFT:NULL,'\E[1;2D'。
    kNXT: NULL, '\E[6;2~'。
    kPRV: NULL, '\E[5;2~'。
    kRIT:NULL,'\E[1;2C'。
    ka1: '\EOq', '\EOw'。
    ka3: '\EOs', '\EOy'。
    kb2: '\EOr', '\EOu'。
    kc1: '\EOp', '\EOq'。
    kc3: '\EOn', '\EOs'。
    肯德:'\E[4~','\EOF'。
    kf0: '\EOy', NULL。
    kf1: '\E[11~', '\EOP'。
    kf13: '\E[25~', '\E[1;2P'。
    kf14: '\E[26~', '\E[1;2Q'。
    kf15: '\E[28~', '\E[1;2R'。
    kf16: '\E[29~', '\E[1;2S'。
    kf17: '\E[31~', '\E[15;2~'。
    kf18: '\E[32~', '\E[17;2~'。
    kf19: '\E[33~', '\E[18;2~'。
    kf2: '\E[12~', '\EOQ'。
    kf20: '\E[34~', '\E[19;2~'。
    kf21: NULL, '\E[20;2~'。
    kf22: NULL, '\E[21;2~'。
    kf23: NULL, '\E[23;2~'。
    kf24: NULL, '\E[24;2~'。
    kf25: NULL, '\E[1;5P'。
    kf26: NULL, '\E[1;5Q'。
    kf27: NULL, '\E[1;5R'。
    kf28: NULL, '\E[1;5S'。
    kf29: NULL, '\E[15;5~'。
    kf3: '\E[13~', '\EOR'。
    kf30: NULL, '\E[17;5~'。
    kf31: NULL, '\E[18;5~'。
    kf32: NULL, '\E[19;5~'。
    kf33: NULL, '\E[20;5~'。
    kf34: NULL, '\E[21;5~'。
    kf35: NULL, '\E[23;5~'。
    kf36: NULL, '\E[24;5~'。
    kf37: NULL, '\E[1;6P'。
    kf38: NULL, '\E[1;6Q'。
    kf39: NULL, '\E[1;6R'。
    kf4: '\E[14~', '\EOS'.
    kf40: NULL, '\E[1;6S'。
    kf41: NULL, '\E[15;6~'。
    kf42: NULL, '\E[17;6~'。
    kf43: NULL, '\E[18;6~'。
    kf44: NULL, '\E[19;6~'。
    kf45: NULL, '\E[20;6~'。
    kf46: NULL, '\E[21;6~'。
    kf47: NULL, '\E[23;6~'。
    kf48: NULL, '\E[24;6~'。
    kf49: NULL, '\E[1;3P'。
    kf50: NULL, '\E[1;3Q'。
    kf51: NULL, '\E[1;3R'。
    kf52: NULL, '\E[1;3S'。
    kf53: NULL, '\E[15;3~'。
    kf54: NULL, '\E[17;3~'。
    kf55: NULL, '\E[18;3~'。
    kf56: NULL, '\E[19;3~'。
    kf57: NULL, '\E[20;3~'。
    kf58: NULL, '\E[21;3~'。
    kf59: NULL, '\E[23;3~'。
    kf60: NULL, '\E[24;3~'。
    kf61: NULL, '\E[1;4P'。
    kf62: NULL, '\E[1;4Q'。
    kf63: NULL, '\E[1;4R'。
    khome: '\E[1~', '\EOH'。
    种类:'\E[B'、'\E[1;2B'。
    kri: '\E[A', '\E[1;2A'。
    kspd:'^Z',NULL。
    mc0: NULL, '\E[i'.
    mc4: NULL, '\E[4i'。
    mc5: NULL, '\E[5i'。
    meml: NULL, '\El'。
    内存:NULL,'\Em'。
    mgc: NULL, '\E[?69l'。
    nel: '\r\n', NULL。
    oc:'\E]R','\E]104\007'。
    ritm:NULL,'\E[23m'。
    rmacs: '^O', '\E(B'.
    rmcup: '\E[2J\E[?47l', '\E[?1049l\E[23;0;0t'。
    rmm: NULL, '\E[?1034l'。
    rmpch: '\E[10m', NULL。
    rs1: NULL, '\Ec\E]104\007'。
    rs2: '\E'。
    s0ds: '\E[10m', NULL。
    s1ds: '\E[11m', NULL。
    s2ds: '\E[12m', NULL。
    sgr: '\E[0%?%p1%p6%|%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4% t;5%;m%?%p9%t\016%e\017%;', '%?%p9%t\E(0%e\E(B%;\E[0%?%p6% t;1%;%?%p5%t;2%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;% ?%p7%t;8%;m'。
    sgr0: '\E[m\017', '\E(B\E[m'.
    sitm: NULL, '\E[3m'。
    smacs: '^N', '\E(0'.
    smcup: '\E[?47h', '\E[?1049h\E[22;0;0t'。
    smglr: NULL, '\E[?69h\E[%i%p1%d;%p2%ds'。
    smm: NULL, '\E[?1034h'。
    smpch: '\E[11m', NULL。
    tsl: '\E]0;', NULL。
    u8: '\E[?6c', '\E[?%[;0123456789]c'。
    Cr:NULL,'\E]112\007'。
    Cs: NULL, '\E]12;%p1%s\007'。
    Ms: NULL, '\E]52;%p1%s;%p2%s\007'。
    Se:NULL,'\E[2 q'。
    Ss: NULL, '\E[%p1%d q'。
    TS: '\E]0;', NULL。
    kDC3: NULL, '\E[3;3~'。
    kDC4: NULL, '\E[3;4~'。
    kDC5: NULL, '\E[3;5~'。
    kDC6: NULL, '\E[3;6~'。
    kDC7: NULL, '\E[3;7~'。
    kDN:NULL,'\E[1;2B'。
    kDN3: NULL, '\E[1;3B'。
    kDN4:NULL,'\E[1;4B'。
    kDN5:NULL,'\E[1;5B'。
    kDN6:NULL,'\E[1;6B'。
    kDN7:NULL,'\E[1;7B'。
    kEND3: NULL, '\E[1;3F'。
    kEND4: NULL, '\E[1;4F'。
    kEND5: NULL, '\E[1;5F'。
    kEND6: NULL, '\E[1;6F'。
    kEND7: NULL, '\E[1;7F'。
    kHOM3: NULL, '\E[1;3H'。
    kHOM4: NULL, '\E[1;4H'。
    kHOM5: NULL, '\E[1;5H'。
    kHOM6: NULL, '\E[1;6H'。
    kHOM7: NULL, '\E[1;7H'。
    kIC3: NULL, '\E[2;3~'。
    kIC4: NULL, '\E[2;4~'。
    kIC5: NULL, '\E[2;5~'。
    kIC6: NULL, '\E[2;6~'。
    kIC7: NULL, '\E[2;7~'。
    kLFT3: NULL, '\E[1;3D'。
    kLFT4:NULL,'\E[1;4D'。
    kLFT5:NULL,'\E[1;5D'。
    kLFT6:NULL,'\E[1;6D'。
    kLFT7:NULL,'\E[1;7D'。
    kNXT3: NULL, '\E[6;3~'。
    kNXT4: NULL, '\E[6;4~'。
    kNXT5: NULL, '\E[6;5~'。
    kNXT6: NULL, '\E[6;6~'。
    kNXT7: NULL, '\E[6;7~'。
    kPRV3: NULL, '\E[5;3~'。
    kPRV4: NULL, '\E[5;4~'。
    kPRV5: NULL, '\E[5;5~'。
    kPRV6: NULL, '\E[5;6~'。
    kPRV7: NULL, '\E[5;7~'。
    kRIT3: NULL, '\E[1;3C'。
    kRIT4: NULL, '\E[1;4C'。
    kRIT5: NULL, '\E[1;5C'。
    kRIT6: NULL, '\E[1;6C'。
    kRIT7: NULL, '\E[1;7C'。
    kUP: NULL, '\E[1;2A'。
    kUP3: NULL, '\E[1;3A'。
    kUP4: NULL, '\E[1;4A'。
    kUP5: NULL, '\E[1;5A'。
    kUP6: NULL, '\E[1;6A'。
    kUP7:NULL,'\E[1;7A'。
    ka2:NULL,'\EOx'。
    kb1:NULL,'\EOt'。
    kb3:NULL,'\EOv'。
    kc2: NULL, '\EOr'。
    kp1: '\EOq', NULL。
    kp2: '\EOr', NULL。
    kp3: '\EOs', NULL。
    kp4: '\EOt', NULL。
    kp5: '\EOu', '\EOE'。
    kp6: '\EOv', NULL。
    kp7: '\EOw', NULL。
    kp8: '\EOx', NULL。
    kp9: '\EOy', NULL。
    kpADD:'\EOl','\EOk'。
    kpCMA:NULL,'\EOl'。
    kpDIV:'\EOQ','\EOo'。
    kpMUL:'\EOR','\EOj'。
    kpNUM:'\EOP',NULL。
    kpSUB: '\EOS', '\EOm'。
    rmxx: NULL, '\E[29m'。
    smxx: NULL, '\E[9m'。

相关内容