如何从Python的telnet响应中读取一行?

mad*_*245 2 python telnet telnetlib python-3.x python-3.3

我很惊讶我在这里找不到这个问题.

我想从telnet响应中提取一行并使其成为变量.(实际上是该行的一个数字).我可以使用telnet.read_until()提取到我需要的位置,但整个开始仍然存在.打印输出显示机器的不同状态.

我想要获取的行格式如下:

CPU Utilization          : 5 %
Run Code Online (Sandbox Code Playgroud)

我真的只需要数字,但输出的其余部分有很多':'和'%'字符.任何人都可以帮我提取这个价值吗?提前致谢!

这是我的代码(这将读取整个输出并打印):

import telnetlib, time


print ("Starting Client...")
host    = input("Enter IP Address: ")
timeout = 120

print ("Connecting...")
try:
    session = telnetlib.Telnet(host, 23, timeout)
except socket.timeout:
    print ("socket timeout")
else:
    print("Sending Commands...")
    session.write("command".encode('ascii') + b"\r")
    print("Reading...")
    output = session.read_until(b"/r/n/r/n#>", timeout )
    session.close()
    print(output)
    print("Done")
Run Code Online (Sandbox Code Playgroud)

编辑:输出可能是的一些示例:

Boot Version         : 1.1.3 (release_82001975_C)
Post Version         : 1.1.3 (release_82001753_E)
Product VPD Version  : release_82001754_C
Product ID           : 0x0076
Hardware Strapping   : 0x004C
CPU Utilization      : 5 %
Uptime               : 185 days, 20 hours, 31 minutes, 29 seconds
Current Date/Time    : Fri Apr 26 17:50:30 2013
Run Code Online (Sandbox Code Playgroud)

aba*_*ert 6

正如你在问题中所说:

我可以提取到我需要使用的地方telnet.read_until(),但整个开始仍然存在.

因此,您可以将所需的所有行(包括您想要的行)添加到变量中output.你唯一缺少的是如何获得该output字符串中的最后一行,对吧?

这很简单:只需分成output几行并取最后一行:

output.splitlines()[:-1]
Run Code Online (Sandbox Code Playgroud)

或者只是拆掉最后一行:

output.rpartition('\n')[-1]
Run Code Online (Sandbox Code Playgroud)

这不会改变输出,它只是一个计算新值的表达式(最后一行output).所以,这样做,接下来print(output),将不会做任何明显有用的事情.

我们来看一个更简单的例子:

a = 3
a + 1
print(a)
Run Code Online (Sandbox Code Playgroud)

这显然是打印出来的3.如果你想打印4,你需要这样的东西:

a = 3
b = a + 1
print(b)
Run Code Online (Sandbox Code Playgroud)

所以,回到真实的例子,你想要的可能是这样的:

line = output.rpartition('\n')[-1]
print(line)
Run Code Online (Sandbox Code Playgroud)

现在你会看到这个:

CPU Utilization          : 5 %
Run Code Online (Sandbox Code Playgroud)

当然,您仍然需要像Johnny的代码那样从其余部分中提取数字:

numbers = [int(s) for s in line.split() if s.isdigit()]
print(numbers)
Run Code Online (Sandbox Code Playgroud)

现在你会得到这个:

['5']
Run Code Online (Sandbox Code Playgroud)

请注意,它为您提供了一个字符串的列表.如果你只想要一个字符串,你仍然有另一个步骤:

number = numbers[0]
print(number)
Run Code Online (Sandbox Code Playgroud)

哪个给你:

5
Run Code Online (Sandbox Code Playgroud)

最后,number仍然是字符串 '5',而不是整数5.如果您需要,请将最后一位替换为:

number = int(numbers[0])
print(number)
Run Code Online (Sandbox Code Playgroud)

这仍然会打印出来 5,但是现在你有一个变量可以实际用作数字:

print(number / 100.0) # convert percent to decimal
Run Code Online (Sandbox Code Playgroud)

我依赖于telnet定义行尾\r\n的事实,并且任何错误的telnet兼容的服务器几乎肯定会使用Windows风格(也\r\n)或Unix风格(只是\n)行尾.因此,拆分\n将始终获得最后一行,即使对于棘手的服务器也是如此.如果您不需要担心额外的稳健性,可以拆分\r\n而不是\n.


还有其他方法可以解决这个问题.我可能会使用类似的东西session.expect([r'CPU Utilization\s*: (\d+)\s*%']),或者将会话包装为行的迭代器(如文件),然后编写标准itertools解决方案.但鉴于你已经拥有的东西,这似乎是最简单的.