Skip to main content
 首页 » 编程设计

python之如何在终端窗口中打印/显示 telnet session 的输出 (Python)

2025年05月04日15Leo_wl

有人可以帮助理解终端窗口中的打印是如何工作的吗? 这是一个测试脚本

测试脚本.py

import telnetlib 
HOST = "10.1.1.151" 
tn = telnetlib.Telnet(HOST) 
tn.open(HOST) 
test_var = ["test"] 
print test_var 
tn_read =  tn.read_very_eager() 
print tn_read 

从终端运行脚本时的输出:

$ python test_script.py 
  ['test'] 

tn_read 应该类似于“用户名:”,但它不会打印在终端窗口中。

如果我从解释器运行它,我会得到预期的结果:

 >>> tn.read_very_eager() 
 '\n\rUser Name : ' 

当从终端调用脚本时,为什么或需要做什么才能得到以下输出?

 $ python test_script.py 
  ['test'] 
  User Name :   

请您参考如下方法:

简短的回答是使用带有超时的read_until()。例如

timeout = 3    # seconds 
tn_read = tn.read_until('User Name :', timeout) 
print repr(tn_read) 

下面是长答案。

read_very_eager() 是非阻塞的,它会返回任何已经可用的熟数据,但如果没有任何数据则什么也不会返回。如果在建立连接后过早调用非阻塞“读取”方法,可能没有数据可读,read_very_eager() 将返回一个空字符串 - ''.

所以你的问题可能与时间有关;读取是非阻塞的,不能返回尚未接收、处理和缓冲的数据。当您通过终端进行交互时,您需要时间来输入命令,因此您不会注意到时间问题,但是当从脚本运行时,人为延迟被移除,并且时间问题变得明显。在调用 read 方法之前尝试休眠:

import telnetlib 
import time 
 
HOST = "10.1.1.151" 
tn = telnetlib.Telnet(HOST) 
test_var = ["test"] 
print test_var 
time.sleep(5) 
tn_read =  tn.read_very_eager() 
print repr(tn_read) 

将上面的代码作为脚本运行,您可能会看到预期的输出……但也可能不会。相反,您可能仍会看到:

['test'] 
'' 

也可能有其他因素,特别是服务器可能正在响应 Telnet IAC 序列。 telnetlib 将使用此序列,如果它在您调用 read_very_eager()(实际上是任何读取函数)之前到达。在这种情况下,read_very_eager() 也返回一个空字符串。

如果您想查看通过连接交换的内容,您可以调用 set_debuglevel(1):

导入telnetlib

tn = telnetlib.Telnet('library.cedarville.edu')   # any old server will do 
tn.set_debuglevel(1) 
tn_read =  tn.read_all() 
print repr(tn_read) 

典型的输出是:

Telnet(library.cedarville.edu,23): recv '\xff\xfd\x03' 
Telnet(library.cedarville.edu,23): IAC DO 3 
Telnet(library.cedarville.edu,23): recv '\xff\xfb\x03\xff\xfb\x01\xff\xfd\x18\xff\xfd#\xff\xfd$\xff\xfd\x1f' 
Telnet(library.cedarville.edu,23): IAC WILL 3 
Telnet(library.cedarville.edu,23): IAC WILL 1 
Telnet(library.cedarville.edu,23): IAC DO 24 
Telnet(library.cedarville.edu,23): IAC DO 35 
Telnet(library.cedarville.edu,23): IAC DO 36 
Telnet(library.cedarville.edu,23): IAC DO 31 
Telnet(library.cedarville.edu,23): recv '\r\n' 
Telnet(library.cedarville.edu,23): recv 'login: ' 

在其他“读取”函数中,您可能应该使用 read_until()。如果您不想无限期地阻塞,请将超时传递给它,如上所示。