簡體   English   中英

Python 線程和 Te.net 意外結果

[英]Python Threading and Telnet unexpected results

我編寫了一個腳本,將 te.nets 連接到某些網絡設備並提取庫存並將其放入文件中。 我使用線程來加速腳本,因為我有大約 160 個節點。 我寫了一個 function,te.nets 到每個節點,檢索清單,將 output 寫入文件,然后斷開 session。當我在一個 function 下執行這三個步驟時,腳本工作得很好。但是,我決定創建一個class 並將這三個步驟分解為不同的方法。 現在,當我運行腳本時,它只會從列表中的第一個節點檢索數據。 我需要一些幫助來弄清楚為什么腳本不起作用。

import concurrent.futures
import time
import telnetlib
from myFunctions import get_node_list_TA5K

class Ta5kTelnet:

    def __init__(self):
        self.tn = telnetlib.Telnet()

    def connect(self, hostname, username, password):
        self.tn.open(hostname, 23, 5)
        self.tn.read_until(b'Username:', 5)
        self.tn.write(username.encode('ascii') + b'\n')
        self.tn.read_until(b'Password:', 5)
        self.tn.write(password.encode('ascii') + b'\n')
        if b'>' in self.tn.read_until(b'>', 5):
            self.tn.write(b'en\n')
            self.tn.read_until(b'#', 5)
            self.tn.write(b'term len 0\n')
            output = self.tn.read_until(b'#', 5)
            return output
        else:
            print(f'{hostname} is spare shelf')

    def send(self, command, waitfor):
        self.tn.write(command + b'\n')
        result = self.tn.read_until(waitfor, 180).decode()
        return result
    
    def disconnect(self):
        self.tn.close()


tlnt = Ta5kTelnet()


def inventory(node_names):
    tlnt.connect(node_names, 'username', 'password')
    shelf_inventory = tlnt.send(b'show system inventory', b'#')
    tlnt.disconnect()
    with open(f'{node_names}_inventory.txt', 'a') as f:
        f.write(shelf_inventory)



#adtran_nodes = get_node_list_TA5K()
adtran_nodes = ['BXR1-NODE1-COT1', 'BXR6-NODE1-COT6']


start = time.perf_counter()

with concurrent.futures.ThreadPoolExecutor() as executor:
    results = executor.map(inventory, adtran_nodes)



print(time.perf_counter() - start)

您在兩個線程之間共享一個 te.net 連接,並且沒有鎖定或同步。

沒有實際的方法可以知道連接、登錄、發送、read_until 序列將運行哪個順序。

每個線程都需要自己的連接 object。

此外,我將重構一些東西以從te.netlib.Te.net派生,同時,為了確保連接始終正確關閉,使其成為具有__enter____exit__的上下文管理器:

import concurrent.futures
import telnetlib

USERNAME = "username"
PASSWORD = "password"


class Ta5kTelnet(telnetlib.Telnet):
    def __enter__(self):
        return self

    def __exit__(self, *args):
        self.close()

    def login(self, hostname, username, password):
        self.open(hostname, 23, 5)
        self.read_until(b"Username:", 5)
        self.write(username.encode("ascii") + b"\n")
        self.read_until(b"Password:", 5)
        self.write(password.encode("ascii") + b"\n")
        if b">" in self.read_until(b">", 5):
            self.write(b"en\n")
            self.read_until(b"#", 5)
            self.write(b"term len 0\n")
            return self.read_until(b"#", 5)
        raise RuntimeError(f"{hostname} is spare shelf")

    def send_command(self, command, waitfor):
        self.write(command + b"\n")
        return self.read_until(waitfor, 180).decode()


def get_node_inventory(node_name):
    with Ta5kTelnet() as tlnt:
        tlnt.login(node_name, USERNAME, PASSWORD)
        shelf_inventory = tlnt.send_command(b"show system inventory", b"#")
    with open(f"{node_name}_inventory.txt", "a") as f:
        f.write(shelf_inventory)


adtran_nodes = ["BXR1-NODE1-COT1", "BXR6-NODE1-COT6"]

with concurrent.futures.ThreadPoolExecutor() as executor:
    results = executor.map(get_node_inventory, adtran_nodes)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM