\r"在以下脚本中有什么作用?
我正在使用以下脚本通过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 个回答
\r
是 ASCII 中的回车符(Carriage Return,简称 CR)。
不同的操作系统使用不同的换行方式。最常见的几种有:
- CR+LF(
\r\n
); - LF(
\n
); - CR(
\r
)。
\n\r
(LF+CR)看起来有点不寻常。
补充:根据我对 Telnet RFC 的理解:
- CR+LF 是 telnet 协议中标准的换行方式。
- LF+CR 也是可以接受的替代方式:
按照定义,"CR LF" 这个顺序会让光标移动到下一行的左边缘(就像 "LF CR" 这个顺序一样)。
'\r'
代表“回车”,它和'\n'
(表示“换行”或“新行”)有点像。
在打字机的时代,你需要把写字的部分移动回行的开头,然后再把纸向下移动,才能在下一行写字。
在现代计算机中,我们仍然保留了这种功能,原因有很多。但大多数情况下,我们只使用'\n'
,并自动假设我们想从行的开头开始写,因为不这样做就没什么意义了。
不过,有时候我们只想用'\r'
,比如我想在输出上写东西,而不是换到新的一行去写,而是想覆盖掉我之前写的内容。这就是很多Linux或Windows命令行程序能够在同一行显示“进度”信息的原因。
现在大多数系统只用'\n'
来表示换行,但有些系统会同时使用这两者。
你可以在其他一些回答中看到这些例子的具体情况,最常见的有:
- Windows用
'\r\n'
来结束行 - Mac用
'\r'
来结束行 - Unix/Linux用
'\n'
来结束行
还有一些其他程序也有它们的特定用法。
想了解更多关于这些字符的历史,可以查看这个链接。
字符 '\r'
是回车符,而回车和换行的组合在网络虚拟终端会话中都是需要的,用来表示换行。
根据早期的Telnet规范 (RFC 854)(第11页):
这个“CR LF”的序列会让光标移动到下一行的最左边(就像“LF CR”序列一样)。
不过,根据最新的规范 (RFC5198)(第13页):
...
在Net-ASCII中,CR 不能出现,除非后面紧跟着 NUL 或 LF,而后者(CR LF)表示“换行”功能。现在,CR 一般只在后面跟着 LF 的情况下出现。因为页面布局可以用其他方式更好地处理,而且在某些编程语言中,NUL 有特殊的含义,为了避免其他类型的混淆,最好避免出现 CR NUL。
LF CR 除非是多个 CR LF 序列的副作用(例如,CR LF CR LF),否则不应该出现。
所以在Telnet中,换行应该始终是 '\r\n'
,但大多数实现要么没有更新,要么为了向后兼容,仍然使用旧的 '\n\r'
。