【问题标题】:Python get IP address from telnetlib outputPython 从 telnetlib 输出中获取 IP 地址
【发布时间】:2017-08-31 22:51:51
【问题描述】:

使用 telnetlib,我从路由器中提取路由信息,并希望使用模式提取 WAN IP 地址。 telnet 会话的输出位于一个变量中,其中行由 \n 分隔。

来自 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'
>>> 

现在是我的代码。

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)

我本来希望打印匹配的一行。

Found     inet 24.6.29.214/21 brd 24.6.31.255 scope global eth0

但我到处都能找到。

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 

我无法弄清楚为什么我的代码会失败。如果专家有更好的方法(有解释)那就太好了。

编辑:

Jan 的回答肯定更符合 Python 风格,但我对 Python 的了解不足使我更喜欢 vks,这对我来说更容易理解。我给了两个“^”,并将 vks 标记为首选(在“我首选”的意义上)。

我最终在 '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

【问题讨论】:

  • re.findall() 返回匹配的列表。列表可以为空;不可能是None。对于单个匹配,您需要re.search()(如果匹配必须位于字符串的开头,则需要 re.match()``)。
  • 您的regex works fine(稍作调整),if 结构是问题所在。

标签: python regex


【解决方案1】:
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)

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

您的代码有问题:

1) re.findall 返回 list ,所以它不能是 None 它可以为空。所以在 if 条件下使用它。

2) re.findall 只返回组(如果有的话)。如果你想要整行,让第一组不捕获。

【讨论】:

    【解决方案2】:

    您可以通过列表理解大大缩减您的代码:

    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']
    

    或者,如果您更喜欢 filter()lambda()

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

    【讨论】:

      猜你喜欢
      • 2011-01-27
      • 2018-07-14
      • 1970-01-01
      • 2016-11-06
      • 2011-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多