脚本输出不正确

时间:2018-01-13 21:24:27

标签: multithreading python-3.x queue

我编写了一个脚本,它使用ssh登录到几个盒子并提取他们的序列号,mac地址和IP地址。除非我将信息写入文件,否则一切正常。出于某种原因,程序正在重复每个设备的序列号,即使它记录了正确的IP和MAC地址。脚本的几行输出如下。您注意到即使IP和MAC不同,序列号也是相同的。我有超过9k的盒子需要从中提取这些信息。非常感谢任何指导。

ip地址,序列号,mac地址

10.20.145.245,kamai-19553541,00:03:E6:5F:A4:24

10.36.155.255,kamai-19553541,00:03:E6:5F:AB:68

import paramiko
import time
import threading
from queue import Queue

stb_ips = "stb_ip_alive_test.txt"
IP_Addresses_list = []
result = ''
serial_number = ''
hardware_address = ''
ip_address = ''
stb_serial_number_filename = 'stb_serial_numbers.txt'

def stb_serial_number(q):
    global result
    global serial_number
    global hardware_address
    global ip_address
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    try:
        while True:
            name = threading.current_thread().getName()
            # print('Thread', name, q.qsize(), time.strftime('%H:%M:%S'))
            ip = q.get()
            print('Connecting to ', ip)
            ssh.connect(ip, port=10022, username='xxxx',  
password='xxxx', banner_timeout=70, timeout=70)
            stdin, stdout, stderr = ssh.exec_command('cat /tmp/hostname\n')
            stb_serial_numbers = stdout
            # print(serial_number)
            with open(stb_serial_number_filename, 'w') as f_index:
                f_index.write('ip_address,serial_number,hardware_address\n')
            for line in stb_serial_numbers.readlines():
                serial_number = line.strip()
            stdin, stdout, stderr = ssh.exec_command('/sbin/ifconfig 
eth0\n')
            mac_addresses = stdout
            for mac_address in mac_addresses.readlines():
                if mac_address.startswith('eth0'):
                    tmp = mac_address.split()
                    hardware_address = tmp[4]
                if 'inet' in mac_address:
                    tmp = mac_address.split()
                    ip_address = tmp[1].lstrip('addr:')
                    result += (ip_address + ',' + serial_number + ',' + 
hardware_address + '\n')
            with open(stb_serial_number_filename, 'a') as f:
                f.write(result)
            q.task_done()
    except (TimeoutError, ConnectionResetError, paramiko.SSHException):
        with open('STB_Log_File_' + time.strftime('%m%d%Y%M%S') + '.txt', 
'a') as file_index:
            file_index.write("Error, Connection Timed out or forcibly closed 
while trying to connect to " + ip + '\n')
            ssh.close()

def queue_input(q):
    with open(stb_ips, 'r') as f:
        Ip_Addresses = f.read().splitlines()
    for ip in Ip_Addresses:
        name = threading.current_thread().getName()
        # print('Thread', name, q.qsize(), time.strftime('%H:%M:%S'))
        q.put(ip)
    q.join()

if __name__ == '__main__':
    q = Queue(maxsize=5)
    thread_count = 5
    for i in range(thread_count):
        t = threading.Thread(name='Consumer', target=stb_serial_number, 
args=(q,), daemon=True)
        t.start()
    t = threading.Thread(name='Producer', target=queue_input, args=(q,))
    t.start()
    q.join()

1 个答案:

答案 0 :(得分:0)

当你通过serial_number for循环时,

mac_addresses只有一个值:你在另一个for循环中设置的最后一个值。您将需要捕获该循环中的所有行,使用serial_numbers = [line.strip() for line in stb_serial_numbers]而不是第一个for循环,然后进行第二个循环for serial_number, mac_address in zip(serial_numbers, mac_addresses):

另一方面说明:有时候运行此代码可能会搞乱输出,因为你从不同的线程写入同一个文件。同样,从线程访问全局变量是一个坏主意。相反,使用队列将每个线程的结果返回给主线程并将它们组合在一起。