为什么在脚本(1)的输出中换行符是CR + LF(dos风格)?

为什么在脚本(1)的输出中换行符是CR + LF(dos风格)?

在命令的打字稿中script(即在保存的文件中),换行符是 CR + LF (\r\n),尽管原始换行符(馈送到script)是 LF。为什么?看来这是tty问题,我根本不知道。有人可以在没有详细说明的情况下解释一下吗?

我没有遇到任何麻烦;我只是好奇。 :)(但我认为最好修复它,或者至少应该记录下来。)

我的script is from util-linux, but probably it does not matter much.

答案1

程序输出和捕获的 tty 流(例如typescript)之间存在差异的深层原因是 tty 过去是打印机

在unix之前,文本在行尾总是有一个CRLF,不是因为它被认为是行终止的逻辑表示,而是因为每个字符都有真正的物理意义:将打印头一直向左移动,并推进纸张。

Unix 采用了一种全新的方法:它将磁盘上的文本文件视为本身有用的对象(而不仅仅是打印机的指令),并将行视为逻辑实体。在 UNIX 世界观中,两个字符的行终止符不必要地复杂。

但他们必须使用现有的硬件——打印机和 CRT 哑终端,它们不能识别单个“行尾”字符,而只能用 CR 完成一半工作,用 LF 完成另一半工作。因此必须进行翻译,并且是在最接近该硬件的位置(在 tty 驱动程序中)完成的。

从那时起,一切都是向后兼容的。因此,您有一个坚持使用 CRLF 的终端仿真器,以及一个在程序输出换行符时提供它的 tty 驱动程序。

答案2

输出typescript捕获发送到 pty 的所有字符。例如,如果您使用stty -opost阻止终端驱动程序将换行符正常更改为 CR+LF,那么您将看到输出中只有 LF 字符。

希望有帮助的提示,使用

col -b < typescript

第一次清理文件。

答案3

学习后我自己的答案答案以及评论者伊卡洛斯
您必须区分“文件中的换行符”和“控制台中的换行符”。在控制台中,与直觉相反,真正的换行符是 CRLF,如下所示。

在 UNIX 约定中,文本文件中 LF 表示换行符,反之亦然,LF 表示换行符。 (“你的意思是”,我的意思是用自然语言文本说。)在 DOS 中 CR+LF,等等。好的。每个人都知道。

(Unix) 控制台更复杂。首先你要记住LF和CR是控制码,即可以用来控制控制台,例如加粗、颜色等。

如果将 LF(\n,换行符)输入到控制台,则会得到换行符。问题是,好吧,问题是:(1)可以说,控制台是双层的;它们由过滤器和渲染部分组成。 (临时命名法。)隐藏的(对于普通用户)过滤器将 LF 转换为 CRLF。 (2) 渲染器需要 CRLF(\r\n) 作为普通意义上的换行符。请参阅下文了解更多信息。

该命令创建的typescript文件script (1)记录了字符控制台的输入被过滤。这就是为什么打字稿中的换行符是 CRLF。

详细信息及杂项。事实:

  • 控制台渲染器将 LF 打印为“将光标向下移动一行”,将 CR 打印为“将光标移动到行首”。
  • 您可以通过 关闭 LF->CRLF 转换$ stty -opost并通过 擦除它$ stty opost。 “opost”是“输出后处理”的缩写。
    • 更准确地说,当设置opost时 LF->LFCR 会发生变化 。设置onlcronocr,CR 将在行首时被删除等。参考:POSIX chap 11 "通用终端接口”。
  • 在 Unix 中,“Enter”键与 LF 绑定,在键盘映射术语中称为“Return”。 (看这个问题了解详情。)
  • 还有转义码变体;man 4 console_codes解释说“ESC D”(\eD) 是换行符,“ESC E”(\eE) 是换行符。如果打印它们,“ESC D”是“向下移动光标”,“ESC E”是 CR+LF,无论±opost-ness如何。

要进行一些实验,我建议从单独的控制台进行编写。例如,$ echo -ne '1st\n2nd\r\n3rd\n" > /dev/tty1写入第一个非 X 控制台,并且/dev/pts/0是第一个 X 终端。这不是最方便的方法,但最不模糊。

相关内容