\r"在以下脚本中有什么作用?

36 投票
4 回答
197933 浏览
提问于 2025-04-17 14:12

我正在使用以下脚本通过Telnet重启我的路由器:

#!/usr/bin/env python

import os
import telnetlib
from time import sleep

host = "192.168.1.1"
user = "USER"
password = "PASSWORD"
cmd = "system restart"

tn = telnetlib.Telnet(host)
sleep(1)

tn.read_until("Login: ")
tn.write(user + "\n\r")
sleep(1)

tn.read_until("Password: ")
tn.write(password + "\n\r")
sleep(1)

tn.write(cmd + "\n\r")

我不知道为什么去掉 "\r" 会导致这个代码出错。那么在这个脚本中,"\r" 是干什么的呢?一般情况下我什么时候需要使用 "\r" 呢?

注意:我知道“回车符”的意思,但还是搞不清楚它在我的脚本中是怎么用的。我是在Linux系统上运行这个脚本。

4 个回答

7

\r 是 ASCII 中的回车符(Carriage Return,简称 CR)。

不同的操作系统使用不同的换行方式。最常见的几种有:

  • CR+LF(\r\n);
  • LF(\n);
  • CR(\r)。

\n\r(LF+CR)看起来有点不寻常。

补充:根据我对 Telnet RFC 的理解:

  1. CR+LF 是 telnet 协议中标准的换行方式。
  2. LF+CR 也是可以接受的替代方式:

按照定义,"CR LF" 这个顺序会让光标移动到下一行的左边缘(就像 "LF CR" 这个顺序一样)。

24

'\r'代表“回车”,它和'\n'(表示“换行”或“新行”)有点像。

在打字机的时代,你需要把写字的部分移动回行的开头,然后再把纸向下移动,才能在下一行写字。

在现代计算机中,我们仍然保留了这种功能,原因有很多。但大多数情况下,我们只使用'\n',并自动假设我们想从行的开头开始写,因为不这样做就没什么意义了。

不过,有时候我们只想用'\r',比如我想在输出上写东西,而不是换到新的一行去写,而是想覆盖掉我之前写的内容。这就是很多Linux或Windows命令行程序能够在同一行显示“进度”信息的原因。

现在大多数系统只用'\n'来表示换行,但有些系统会同时使用这两者。

你可以在其他一些回答中看到这些例子的具体情况,最常见的有:

  • Windows用'\r\n'来结束行
  • Mac用'\r'来结束行
  • Unix/Linux用'\n'来结束行

还有一些其他程序也有它们的特定用法。

想了解更多关于这些字符的历史,可以查看这个链接。

42

字符 '\r' 是回车符,而回车和换行的组合在网络虚拟终端会话中都是需要的,用来表示换行。


根据早期的Telnet规范 (RFC 854)(第11页):

这个“CR LF”的序列会让光标移动到下一行的最左边(就像“LF CR”序列一样)。

不过,根据最新的规范 (RFC5198)(第13页):

  1. ...

  2. 在Net-ASCII中,CR 不能出现,除非后面紧跟着 NUL 或 LF,而后者(CR LF)表示“换行”功能。现在,CR 一般只在后面跟着 LF 的情况下出现。因为页面布局可以用其他方式更好地处理,而且在某些编程语言中,NUL 有特殊的含义,为了避免其他类型的混淆,最好避免出现 CR NUL。

  3. LF CR 除非是多个 CR LF 序列的副作用(例如,CR LF CR LF),否则不应该出现。

所以在Telnet中,换行应该始终是 '\r\n',但大多数实现要么没有更新,要么为了向后兼容,仍然使用旧的 '\n\r'

撰写回答