【问题标题】:Struggling to reproduce terminal from The Unix Programming Environment (1983)努力从 Unix 编程环境 (1983) 复制终端
【发布时间】:2016-04-24 16:30:07
【问题描述】:

我一直在阅读 Unix 编程环境 并进行了包含的练习。我知道这项工作有些过时,但我发现它是一个很好的资源。

在第一章中,有一些练习向读者展示了与终端的交互并被要求解释交互。这是一个例子:

练习 1-1。解释发生了什么

$ date\@

在正文中,解释了@ 将被解释为行终止字符。我系统上的等价物是^u,但我可以用stty kill @模拟书中的终端。

根据阅读内容和我的直觉,我希望调用 date\@ 会返回以下内容:

date@: command not found

文字支持这个推理:

如果您在 #@ 前面加上反斜杠 \,则它失去了特殊含义。所以要输入# 或@,请输入\#\@

我的问题是我什至无法在终端中输入示例。只要我输入@,该行就会被删除。反斜杠似乎没有转义行终止字符。

假设我对转义字符应该如何与终端控制字符交互是正确的,我该如何设置我的系统(Ubuntu GNU/Linux)来模拟文本中的行为?

这是另一个类似的练习:

练习 1-2。 大多数 shell(尽管不是第 7 版 shell)将 # 解释为引入注释,并忽略从 # 到行尾的所有文本。鉴于此,假设您的擦除字符也是#,请解释以下脚本:

$ date
Mon Sep 26 12:39:56 EDT 1983
$ #date
Mon Sep 26 12:40:21 EDT 1983
$ \#date
$ \\#date
#date: not found
$

由于我的擦除字符设置为#,因此无法复制此成绩单。反斜杠似乎没有转义擦除字符。

【问题讨论】:

    标签: linux unix terminal


    【解决方案1】:

    终端在 Shell 之前获取并响应您的击键。所以shell没有机会逃脱@,因为终端首先删除了整行。

    当你输入时

    stty kill @
    

    你告诉 shell 告诉终端在你每次按 @ 时终止该行

    类型

    stty kill ^u
    

    你的 shell 将开始按照你期望的方式运行,并且 ^u 会为你杀死行。

    ^v 是终端的转义字符
    \ 是 shell 的转义字符。

    【讨论】:

    • 恐怕这不能回答我的问题。我了解如何恢复终端的原始行为。我想知道为什么用反斜杠转义 line kill 字符似乎没有任何效果。
    • 因为终端首先读取行终止字符。不留行供 shell 读取。你与终端对话,终端与 shell 对话。如果您告诉终端终止一行,它不会将该行发送到 shell。
    • 文中暗示内核内部还有另一种解释反斜杠的机制:“当擦除或行终止字符前面有反斜杠时,内核丢弃反斜杠并保留以下内容没有解释的字符”。现在不是这样了吗?有没有办法模仿这种行为?
    • 您描述的行为是所有shell的工作方式。你的也不一样。您似乎缺少的一点是终端不是外壳。它们是两种不同的东西。
    • 我明白这一点。请参阅我添加的澄清示例。
    【解决方案2】:

    这是一个古老的问题,关于一本更古老的书,但我想在这里直接记录,因为当前接受的答案没有回答您的问题。

    信不信由你,当我在 1985 年(!)从这本书中学习 UNIX 时,这本书的这一部分已经过时了,关于“#”、“@”和“\”的东西已经不起作用了,我记得我和你一样困惑为什么它不起作用,以及我是否做错了什么。但这本身并没有错——只是过时了。让我解释一下在以前的时代(可能是这本书出版之前的十年?)这些东西是正确的:

    在 CRT 终端出现之前,有“电传打字机”终端 - 基本上是打字机,可以在纸上打印您输入的字符(以及远程响应)。在这样的电传打字机上,没有“退格”。您无法删除已经输入的内容。所以约定是你输入一个“#”,它会从逻辑上删除前一个字符。您仍然会在纸上看到它们,但不得不想象它们都已从计算机的输入中删除。所以如果你在纸上看到

    helk#lo world
    

    计算机实际上收到了“hello world”,“#”删除了它后面的“k”。 如果您犯了很多错误,UNIX 还允许您输入一个字符“@”来删除您刚刚输入的 整个 行。所以

    oops I wrote a lot of crap I need to erase@hello world
    

    再次被解释为“hello world”。

    最后,由于有时您想键入一个实际的“#”或“@”字符并让它们按字面意思理解,而不是作为字符擦除或行擦除命令,因此您还有一个“转义字符”,它在很早的时候是“\”。请注意,这个转义字符不是由 shell 解释的,而是由 Unix 内核的终端驱动程序解释的,它与电传打字机通信。

    当新的 CRT 终端出现时,这些约定很快就被淘汰,变成了我们今天所知道的:默认的擦除字符不再是“#”而是退格键或删除键,它确实擦除了屏幕上的字符.行擦除(有点混淆地称为“kill”)变成了 control-X 或 control-U。转义字符变为 control-V。您还可以使用“stty”命令更改这些字符,设置“erase”、“kill”或“lnext”属性,但人们很少这样做。 "stty -a" 显示这些特殊字符(以及更多)的所有当前设置。

    【讨论】:

    • 无论如何,要在现代机器上“重现”古老的终端感觉,请执行以下操作: stty erase '#'; stty kill '@'; stty lnext '\'。然后运行在原始模式下不起作用的东西 - 例如,“猫”,并看到旧的行为变得栩栩如生:-) 请注意,在现代终端上,# 和 @ 字符实际上会删除之前出现的内容 - 这没有不会发生在电传打字机上,您必须想象它会发生:-)
    猜你喜欢
    • 2015-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-13
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    相关资源
    最近更新 更多