简体   繁体   English

Python从telnetlib输出获取IP地址

[英]Python get IP address from telnetlib output

Using telnetlib I pull routing info from my router and want to extract the WAN IP address using a pattern. 使用telnetlib我从路由器中提取路由信息,并希望使用模式提取WAN IP地址。 The output of the telnet session is in a variable with lines separated by \\n. telnet会话的输出位于变量中,行以\\ n分隔。

The stuff from the telnet session. 来自telnet会话的东西。

l= tn.read_all()
>>> l
'\r\nip -f inet addr\r\nexit\r\nadmin4asus@RT-AC68U:/tmp/home/root# ip -f inet addr\r\n1: lo: <LOOPBACK,MULTICAST,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN \r\n    inet 127.0.0.1/8 brd 127.255.255.255 scope host lo\r\n2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000\r\n    inet 24.6.29.214/21 brd 24.6.31.255 scope global eth0\r\n7: br0: <BROADCAST,MULTICAST,ALLMULTI,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN \r\n    inet 192.168.11.1/24 brd 192.168.11.255 scope global br0\r\n8: tun21: <POINTOPOINT,MULTICAST,NOARP,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 100\r\n    inet 10.8.0.1 peer 10.8.0.2/32 scope global tun21\r\nadmin4asus@RT-AC68U:/tmp/home/root# exit\r\n'
>>> 

Now my code. 现在我的代码。

l= tn.read_all()
for line in l.split('\n'):
    match= re.findall( r'([0-9]+(?:\.[0-9]+){3}).*scope global eth0', line)
    if match is not None:
        print('Found ' + line)

I would have expected the one line that matches to print. 我原本期望匹配的一行打印。

Found     inet 24.6.29.214/21 brd 24.6.31.255 scope global eth0

But I get the find everywhere. 但我到处都找到了。

Found 
Found ip -f inet addr
Found exit
Found admin4asus@RT-AC68U:/tmp/home/root# ip -f inet addr
Found 1: lo: <LOOPBACK,MULTICAST,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN 
Found     inet 127.0.0.1/8 brd 127.255.255.255 scope host lo
Found 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000
Found     inet 24.6.29.214/21 brd 24.6.31.255 scope global eth0
Found 7: br0: <BROADCAST,MULTICAST,ALLMULTI,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN 
Found     inet 192.168.11.1/24 brd 192.168.11.255 scope global br0
Found 8: tun21: <POINTOPOINT,MULTICAST,NOARP,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 100
Found     inet 10.8.0.1 peer 10.8.0.2/32 scope global tun21
Found admin4asus@RT-AC68U:/tmp/home/root# exit
Found 

I can't figure out why my code is failing. 我无法弄清楚为什么我的代码失败了。 If the experts have a better method (with explanation) that would be great. 如果专家有更好的方法(有解释),那将是很好的。

Edit : 编辑:

Jan's answer is surely more pythonic, but my lack of knowledge of python makes me prefer vks which is easier to understand for me. Jan的答案肯定更加pythonic,但我对python的缺乏使我更喜欢vks,这对我来说更容易理解。 I gave both a '^' and will mark vks as preferred (in the sense 'preferred by me'). 我给了两个'^'并且将vks标记为首选(在'我喜欢'的意义上)。

I ended up using '\\r\\n' in the 'split' cmd and following code. 我最终在'split'cmd和代码中使用'\\ r \\ n'。

def get_asus_wan_ip():
    "Gets WAN IP from ASUS router"

    import telnetlib
    import re

    ASUS_IP=   '192.168.1.1'
    ASUS_USER= 'xxxxxxxx'
    ASUS_PASS= 'yyyyyyyy'
    tn = telnetlib.Telnet(ASUS_IP)

    tn.read_until("login: ")
    tn.write(ASUS_USER + "\n")
    tn.read_until("Password: ")
    tn.write(ASUS_PASS + "\n")
    tn.write("ifconfig eth0\n")
    tn.write("exit\n")
    l= tn.read_all()
    for line in l.split('\r\n'):
        match= re.findall( r'^\s+inet addr:([0-9]+(?:\.[0-9]+){3}).*', line)
        if match:
            break

    wan_ip= match[0]
    return wan_ip
import re
x="""'\r\nip -f inet addr\r\nexit\r\nadmin4asus@RT-AC68U:/tmp/home/root# ip -f inet addr\r\n1: lo: <LOOPBACK,MULTICAST,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN \r\n    inet 127.0.0.1/8 brd 127.255.255.255 scope host lo\r\n2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000\r\n    inet 24.6.29.214/21 brd 24.6.31.255 scope global eth0\r\n7: br0: <BROADCAST,MULTICAST,ALLMULTI,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN \r\n    inet 192.168.11.1/24 brd 192.168.11.255 scope global br0\r\n8: tun21: <POINTOPOINT,MULTICAST,NOARP,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 100\r\n    inet 10.8.0.1 peer 10.8.0.2/32 scope global tun21\r\nadmin4asus@RT-AC68U:/tmp/home/root# exit\r\n'"""
for line in x.split('\n'):
    match= re.findall(r'(?:[0-9]+(?:\.[0-9]+){3}).*scope global eth0', line)
    if match:
        print('Found ' + line)

Output: Found inet 24.6.29.214/21 brd 24.6.31.255 scope global eth0 输出: Found inet 24.6.29.214/21 brd 24.6.31.255 scope global eth0

Problems with your code: 代码问题:

1) re.findall returns list , so it cannot be None it can be empty.So use that in if condition. 1) re.findall返回list ,因此它不能为None它可以为空。所以在if条件中使用它。

2) re.findall returns only groups if there are some.If you want the whole line, make the first group non capturing. 2) re.findall只返回组中的组。如果你想要整行,则使第一组不捕获。

You could vastly shrink your code with a list comprehension: 您可以通过列表理解大大缩小代码:

import re

string = """
1: lo: <LOOPBACK,MULTICAST,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN 
    inet 127.0.0.1/8 brd 127.255.255.255 scope host lo
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000
    inet 24.6.29.214/21 brd 24.6.31.255 scope global eth0
7: br0: <BROADCAST,MULTICAST,ALLMULTI,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN 
    inet 192.168.11.1/24 brd 192.168.11.255 scope global br0
8: tun21: <POINTOPOINT,MULTICAST,NOARP,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 100
    inet 10.8.0.1 peer 10.8.0.2/32 scope global tun21
"""

rx = re.compile(r'\b(\d+(?:\.\d+){3})\b.*scope global eth0')
matches = [line
            for line in string.split("\n")
            for match in [rx.search(line)]
            if match]
print(matches)
# ['    inet 24.6.29.214/21 brd 24.6.31.255 scope global eth0']

Or if you prefer filter() and lambda() : 或者如果您更喜欢filter()lambda()

matches = list(filter(lambda x: rx.search(x), string.split("\n")))
print(matches)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM