当我查看终端模拟器的长度和宽度时,stty size
它是 271 个字符长和 71 行高。当我通过 SSH 登录到另一台服务器并执行 时stty size
,它也是 271 个字符长和 71 行高。我什至可以登录某些 Cisco IOS 设备,并且终端仍然有 271 个字符长和 71 行高:
C1841#show terminal | i Len|Wid
Length: 71 lines, Width: 271 columns
C1841#
现在,如果我在本地计算机中调整终端模拟器(Gnome 终端)窗口的大小,则stty size
远程服务器和 IOS 中的“显示终端”都会显示不同的行长度和行数。终端长度和宽度如何通过 SSH 和 telnet 转发?
答案1
telnet 协议,描述于RFC 854,包括一种发送带内命令的方法,包括IAC 字符, '\255'
, 后面跟着几个字节。这些命令可以执行诸如向远程发送中断之类的操作,但通常它们用于发送选项。
详细查看发送的交换终端类型选项可以在中找到微软Q231866。
这窗口大小选项描述于RFC 1073。客户端首先发送其发送NAWS
选项的意愿。如果服务器回复DO NAWS
,则客户端可以发送NAWS
选项数据,该数据由两个 16 位值组成。
示例会话,在 47 行 80 列终端上:
telnet> set options
Will show option processing.
telnet> open localhost
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
SENT WILL NAWS
RCVD DO NAWS
SENT IAC SB NAWS 0 80 (80) 0 47 (47)
ssh 协议描述于RFC 4254。它由消息流组成。其中一个消息是"pty-req"
,它请求一个伪终端,其参数包括终端的高度和宽度。
byte SSH_MSG_CHANNEL_REQUEST
uint32 recipient channel
string "pty-req"
boolean want_reply
string TERM environment variable value (e.g., vt100)
uint32 terminal width, characters (e.g., 80)
uint32 terminal height, rows (e.g., 24)
uint32 terminal width, pixels (e.g., 640)
uint32 terminal height, pixels (e.g., 480)
string encoded terminal modes
telnet 和 ssh 客户端将捕获SIGWINCH
信号,因此如果您在会话期间调整终端窗口的大小,它们将向服务器发送一条具有新大小的适当消息。 ssh 发送窗口尺寸更改消息:
byte SSH_MSG_CHANNEL_REQUEST
uint32 recipient channel
string "window-change"
boolean FALSE
uint32 terminal width, columns
uint32 terminal height, rows
uint32 terminal width, pixels
uint32 terminal height, pixels
答案2
我怀疑是通过信号SIGWINCH
——可能是通过管道传递的。
从维基百科:
SIGWINCH The SIGWINCH signal is sent to a process when its controlling terminal changes its size (a window change).
如果我做(在zsh
):
[romano:~] 1 % TRAPWINCH() {echo hi;}
...我修改了终端大小:
[romano:~] % stty size
35 99
[romano:~] % hi
[romano:~] % hi
[romano:~] % hi
[romano:~] % stty size
31 80
答案3
RFC 4254 第 6.9 节消息名称“window-change”与新尺寸一起发送。在客户端,原始 SIGWINCH 可能确实被捕获,但我相信它是通过该消息发送的。 https://www.ietf.org/rfc/rfc4254.txt