为什么 ^M 和 \r 的行为不一致?

为什么 ^M 和 \r 的行为不一致?

也许已经有一些答案可以间接回答我的问题,但我已经阅读了其中的许多答案,但尚未找到针对这种差异的令人满意的答案。

回车的最初含义来自于老式的电传打印机:它的意思是在当前行中将打印头向左移动。如果继续在当前行写入,则会覆盖已经写入的内容。如今,我们可以使用文本符号 指定此行为\r,该文本符号在字符串中显式键入。例如,在 Python 中您可以执行print('hello\rgoodbye'),在终端中您可以执行echo $'hello\rgoodbye',并且在这两种情况下您都只会看到goodbye

相反,伪回车符也可以与 ASCII 控制字符^M(用Ctrl-M或 用键入Enter)交互插入。我称其为伪回车,因为尽管它被广泛称为回车,但令人惊讶的是它不是 insert \r,而是 insert \n,这是新行的符号。

因此,交互式输入hello, then Ctrl-M, then goodbye,令人惊讶的是并没有达到 的等价物hello\rgoodbye,而是达到 的等价物hello\ngoodbye

这不是很矛盾吗?这背后的理由是什么?

答案1

这是终端输入处理的结果:默认情况下,终端设备驱动程序(操作系统内核中用于处理来自终端的输入的软件,而不是终端本身)转换CtrlMCtrlJ.你可以通过运行看到这一点

od -t x1

然后输入两个字符:

$ od -t x1
^M
^J
^D
0000000 0a 0a
0000002

(您不会^M在屏幕上看到等。)

因此,当您键入 时CtrlM,无论哪个程序正在处理您的输入,都不会看到回车符,而是会看到换行符。

这可以通过配置stty icrnl。看了解 Return、Enter 和 stty icrlf对于类似的问题。

相关内容