我对终端terminal
但在上个星期,我运用 xterm.js在浏览器中显现了一个交互式终端,我总算想到要问一个适当根本的问题:当你在终端中按下键盘上的一个键(比方Delete
Escape
a
像平常相同,咱们将经过做一些试验来答复这个问题,看看会产生什么 : )
长途终端是十分陈旧的技能
首要,我想说的是,用 xterm.js
例如,这儿有一张 70 时代或 80 时代的 VT100 终端的相片。这看起来像是一台核算机(它有点大!),但它不是 —— 它仅仅显现实践核算机发送的任何信息。
EC_VT100_terminal.jpg">
当然,在 70 时代,他们并没有运用 Websocket 来做这个,但来回发送的信息的方法和其时差不多。
(相片中的终端是来自西雅图ed
发送了什么信息?
很明显,假如你想连接到一个长途核算机(用 ssh
xterm.js
具体来说:
客户端ls -l
服务器
让咱们看看一个真实的程序,它在浏览器中运转一个长途终端,看看有哪些信息会被来回发送!
咱们将运用 goterm 来进行试验
我在 GitHubGoxterm.js
我 复刻了它,使它能与最新的xterm.js
让咱们来看看在几个不同的终端交互过程中的发送和接纳状况吧!
示例:ls
首要,让咱们运转 ls
xterm.js
~:/play$ lsfile~:/play$
recv
)
sent: "l"recv: "l"sent: "s"recv: "s"sent: "r"recv: "rnx1b[?2004lr"recv: "filern"recv: "x1b[~:/play$ "
我在这个输出中注意到 3 件事:
回显:客户端发送 l
l
l
l
换行:当我按下回车键时,它发送了一个 r'(回车)符号,而不是
转义序列:x1b
ASCII转义字符x1b[?2004h
好了,现在咱们来做一些略微杂乱的工作。
示例:Ctrl+C
接下来,让咱们看看当咱们用 Ctrl+C
~:/play$ cat^C~:/play$
而这儿是客户端发送和接纳的内容。
sent: "c"recv: "c"sent: "a"recv: "a"sent: "t"recv: "t"sent: "r"recv: "rnx1b[?2004lr"sent: "x03"recv: "^C"recv: "rn"recv: "x1b[?2004h"recv: "~:/play$ "
当我按下 Ctrl+C
x03
x03
Ctrl+C
x03
我信任当咱们按 Ctrl+C
cat
Linuxx03
SIGINT
示例:Ctrl+D
让咱们试试彻底相同的工作,仅仅用 Ctrl+D
~:/play$ cat~:/play$
而这儿是发送和接纳的内容:
sent: "c"recv: "c"sent: "a"recv: "a"sent: "t"recv: "t"sent: "r"recv: "rnx1b[?2004lr"sent: "x04"recv: "x1b[?2004h"recv: "~:/play$ "
它与 Ctrl+C
x04
x03
x04
Ctrl + 其它字母呢?
接下来我开端猎奇 —— 假如我发送 Ctrl+e
事实证明,这仅仅该字母在字母表
Ctrl+a
Ctrl+b
Ctrl+c
Ctrl+d
...Ctrl+z
别的,Ctrl+Shift+b
Ctrl+b
0x2
键盘上的其他键呢?下面是它们的映射状况:
Tab
Ctrl+I
Escape
x1b
Backspace
x7f
Home
x1b[H
End
x1b[F
Print Screen
x1bx5bx31x3bx35x41
Insert
x1bx5bx32x7e
Delete
x1bx5bx33x7e
我的 Meta
那 Alt
Alt
Escape
在字面上是相同的,仅仅按Alt
Escape
alt + d
x1bd
alt + shift + d
x1bD
诸如此类
让咱们再看一个比方!
示例:nano
你能够看到一些来自用户界面的文字,如 “GNU nano 6.2”,而这些 x1b[27m
ANSI
上面这些 nano
x1b[
x1b
维基百科
举个简略的比方:假如你在终端运转
echo
它将打印出 “hi there”,其间 “hi” 是赤色的,“there” 是黑色的。本页有一些关于色彩和格式化的转义代码的比方。
我认为有几个不同的转义代码规范,但我的了解是,人们在 Unix
转义代码是为什么你的终端会被搞乱的原因,假如你 cat
二进制cat
0x1b
能够手动输入转义序列吗?
在前面几节中,咱们谈到了 Home
x1b[H
Escape + [ + H
Escape
x1b
假如我在 xterm.js
Escape
[
H
Home
我注意到这在我的电脑上的 Fish shell 中不起作用 —— 假如我键入 Escape
[
[
超时
明显,这在 Fish shell 中能够用 fish_escape_delay_ms
set fish_escape_delay_ms 1000
终端编码有点古怪
我想在这儿暂停一下,我觉得你按下的键被映射到字节的方法是十分古怪的。比方,假如咱们今日从头开端规划按键的编码方法,咱们或许不会把它设置成这样:
Ctrl + a
Ctrl + Shift + a
Alt
Escape
操控序列(如色彩/移动光标)运用与 Escape
Escape
但一切这些都是在 70 时代或 80 时代或什么时候规划的,然后需求永久坚持不变,以便向后兼容,所以这便是咱们得到的东西 :smiley:
改动窗口巨细
在终端中,并不是一切你能做的工作都是经过来回发送字节产生的。例如,当终端被调整巨细时,咱们有必要以不同的方法告知 Linux 窗口巨细现已改动。
下面是 goterm中用来做这件事的 Go 代码的姿态:
syscall.Syscall(syscall.SYS_ioctl
这是在运用 IO
体系调用。我对ioctl
syscall.TIOCSWINSZ
ioctl
这也是 xterm 的工作方法。
在这篇文章中,咱们一直在评论长途终端,即客户端和服务器在不同的核算机上。但实践上,假如你运用像 xterm 这样的终端模拟器,一切这些工作方法都是彻底相同的,仅仅很难注意到,由于这些字节并不是经过网络连接发送的。
文章到此结束啦
关于终端,必定还有许多东西要了解(咱们能够评论更多关于色彩,或许原始与熟化形式,或许 Unicode
感谢 Jesse Luehrs答复了我关于终端的十亿个问题,一切的过错都是我的 :smiley:
via: jvns.ca/blog/2022/07/20/pseudoterminals/
本文由 LCTT原创编译,Linux我国荣誉推出