“esc"的 VT100 转义码是什么?键盘键本身

2022-01-18 00:00:00 python escaping serial-port

问题描述

我正在编写一个脚本来导航基于文本的菜单系统,使用 python 的 telnetlib 访问串行连接.

I'm writing a script to navigate a text-based menu system, using python's telnetlib to access a serial connection.

我可以使用转义码愉快地按下 F 键.例如F9 = "33OX",其中 "33" 是转义序列.

I can happily press the F-keys, using the escape codes. e.g. F9 = "33OX", where "33" is the escape sequence.

如何编码esc"键盘键?我原以为只有33",但这似乎不起作用.

How do I encode the "esc" keyboard key? I would have expected just "33", but that doesn't seem to work.


解决方案

VT-100(或其他使用转义序列的终端)上的 ESC 键没有转义序列"之类的东西.

There is no such thing as an "escape sequence" for the ESC key on a VT-100 (or other terminals that used escape sequences).

转义字符 ASCII 27 用于指示以下字符序列具有特殊含义.这通常将终端放入一个简单的状态机.一般来说,规则是吞下传入的字符,直到看到一个字母或符号字符,包括在内,尽管一些特殊情况,例如可能抓住一个额外字符的符号,例如ESC # 6 转为双角字符.

The escape character, ASCII 27, was used to indicate that the following sequences of characters had special meaning. This usually put the terminal into a simple state machine. In general the rule was to swallow the incoming characters until an alphabetic or symbolic character was seen, inclusively, although some special cases such as symbols which might grab one additional character, e.g. ESC # 6 to double-width characters.

例如在 H-19/VT-52 终端上,ESC H 表示 home,ESC E 表示清屏和 home,ESC J 表示清屏到结束等.VT-100 系列使用 ESC [ H 表示home,ESC [ 2 J 清除到屏幕结束.

For instance on a H-19 / VT-52 terminal, ESC H meant home, ESC E meant clear screen and home, ESC J meant clear to end of screen, etc. The VT-100 series used ESC [ H for home, and ESC [ 2 J for clear to end of screen.

真正发生的是左方括号(没有右方括号)表示参数列表(通常是数字)即将到来.ESC [ 2 J 中的2"表示从光标到顶部(零)和从光标到末尾(一).将 J 切换到 K,现在它会以同样的方式清除线条,而不是屏幕.他们不是任意的.甚至 ESC [ 行 ;col H 将采用数字行/列,例如ESC [ 12;34 H 将转到第 12 行第 34 列.不提供它们采用默认值.

What was really going on was that the open square bracket (there was no close bracket) said that a list of arguments, usually numeric, was coming. The '2' in the ESC [ 2 J meant both from the cursor to the top (zero), and from the cursor to the end (one). Switch the J to a K, and now it would clear the line, rather than the screen, the same way. They weren't arbitrary. Even ESC [ row ; col H would take a numerical row/col, e.g. ESC [ 12; 34 H would go to row 12, column 34. Not providing them took default values.

理论上,服务器不应该给你一个无意义的孤立 ESC 字符,因为终端会坐在那里等待序列.

In theory the server should never throw you a meaningless orphaned ESC character as the terminal would sit there and wait for a sequence.

当您按下功能键时,终端会发送一个 ESC 字符,然后是功能键、箭头或操作的一些预设序列.例如 ESC [ 21 ~ 是 F10.

When you pressed a function key, the terminal would send an ESC character followed by some pre-canned sequence for a function key, arrow, or action. For instance ESC [ 21 ~ was F10.

这就留下了一个非常现实的问题,即如何发送文字孤立的 ESC.有两种方法.

This then left the very real problem of how to send a literal orphaned ESC. There were two ways.

一,发送ESC,然后延迟一段时间.主持人不仅有责任观察进来的东西,而且有责任观察什么时候进来的.并且,假设终端会立即在其缓冲区中发送一个字符块,它会在内部超时,并将 ESC 仅表示 ESC.延迟不必很长.

One, send the ESC and then delay for some amount. The host would have the responsibility of watching not just what came in, but when. And, working under the assumption that a terminal would send a block of characters in its buffer immediately, it would internally time out and take ESC to mean just ESC. The delay did not have to be long.

第二,要求用户为每个所需的文字 ESC 按两次 ESC.由于没有转义序列包含双转义字符,因此它表示特殊情况.这与我们在字符串中引用反斜杠字符时所做的完全相同,"实际上意味着",因为我们必须满足编译器的词法阶段.在这种情况下,它是主机服务器.请记住,在串口时代,也就是在使用这些终端时,当按下一个字符时,它会立即发送.仅仅几年后,我们才开始模拟终端,因此需要模拟它们的转义序列,而不是从内容流中取出行为.

Two, require the user to press ESC twice for every literal ESC desired. As no escape sequence ever consisted of a double escape character, it signaled a special condition. It exactly the same thing we do when quoting backslash characters in strings, a "" really means a "" because we have to satisfy the compiler's lexical phase. In this case, it's the host server. Remember, in the days of serial ports, which was when these terminals were in use, when a character was pressed, it was sent immediately. Only years later did we start emulating terminals and thus rose the need to emulate their escape sequences rather than taking the behaviors out of the content stream.

当然,无效"的 ESC 序列意味着 ESC 是字面的,但这需要先查看后面的字节是什么,然后才能对它们采取行动(因此是超时解决方案).问题是有时这些字符会对应用程序造成副作用,令人讨厌的,有趣的情况可能会出现,试图天真地伪造系统可能会给你带来麻烦.例如,使用 ESC Space 强制退出,ESC 会取消一个提示,但空格会无意中确认下一个提示.

Of course, an 'invalid' ESC sequence meant the ESC was literal, but this required seeing what the following bytes were before you could act on them (hence the timeout solution). The problem is sometimes those characters caused side effects to an application, nasty ones, and interesting cases could arrive where trying to naively fake out the system could get you into trouble. e.g., use ESC Space to force the escape through, the ESC cancels one prompt, but the space unintendedly acknowledges the next.

该问题的第三个解决方案是简单地让主机完全忽略特殊功能键并将传入的字节流作为文字.例如,每次按下 ESC 时,TECO 编辑器都会向用户显示一个美元符号,因为它使用它作为命令分隔符,就像今天在编码中使用分号一样.

The third solution to the problem was to simply have the host ignore special function keys altogether and take the incoming byte stream as literal. For instance, the TECO editor would display a dollar sign to the user each time the ESC was pressed, as it used this for a command separator the same way one might use a semicolon in coding today.

相关文章