无法从python3 / paramiko捕获多个异常

时间:2019-07-25 00:10:55

标签: python python-3.x error-handling try-catch paramiko

在python3中,我使用multiprocessing.Pool并行运行paramiko以连接到子网上的每个ssh设备。我遇到了一系列似乎无法捕获的错误。

我在这里放置了各种try / except语句,但没有一个捕获此错误。我什至用try / except封装了Pool设置和语句,但在那里没有任何变化。所有paramiko内容都在try_login函数中,因此它应该来自try_login函数,但所有内容都在try / except中,甚至还有一个泛型,除了应该可以获取所有内容。

我还尝试过组合导致此输出的异常。

#!/usr/bin/env python3

import paramiko
import socket
import ipaddress

network_address = '192.168.50.0/24'
username = ''
password = ''
timeout = 3
num_threads = 30

def trylogin(ipaddress):
    global username, password
    try:
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect(ipaddress, username=username, password=password, timeout=timeout)
        (stdin, stdout, stderr) = ssh.exec_command('cat /var/serial_number')
        imei = stdout.readline()
        if imei != '': print("[+] {}: Success! Found ".format(ipaddress))
        return [ipaddress, imei]
    except paramiko.AuthenticationException:
        print("[-] {}: Authentication Exception!".format(ipaddress))
    except paramiko.SSHException:
        print("[-] {}: SSH Exception!".format(ipaddress))
    except (paramiko.ssh_exception.SSHException, OSError, EOFError):
        pass
    except EOFError:
        pass
    except OSError:
        pass
    except paramiko.ssh_exception.NoValidConnectionsError:
        pass
    except paramiko.ssh_exception.SSHException:
        pass
    except Exception as e:
        print('caught a new fish')
        print(e)
        pass
    finally:
        try:
            ssh.close()
        except:
            pass
    return

network = ipaddress.ip_network(network_address)
for ipaddr in network.hosts():
    print('Checking {}'.format(str(ipaddr)))
    trylogin(str(ipaddr))

运行此操作时会发生的事情是大多数应该发生的事情。但是我收到一个错误,显示了我认为已处理的两个异常。首先是OSError,然后是paramiko.ssh_exception.SSHException。我不明白为什么我不能把它们困住。

$ ./find_ssh.py
[-] 192.168.50.1 trying...
[-] 192.168.50.2 trying...
[-] 192.168.50.3 trying...
[-] 192.168.50.4 trying...
[-] 192.168.50.5 trying...
[-] 192.168.50.6 trying...
[-] 192.168.50.7 trying...
[-] 192.168.50.8 trying...
[-] 192.168.50.9 trying...
[-] 192.168.50.10 trying...
[-] 192.168.50.10: Authentication Exception!
[-] 192.168.50.11 trying...
[-] 192.168.50.12 trying...
[-] 192.168.50.13 trying...
[-] 192.168.50.14 trying...
[-] 192.168.50.14: SSH Exception!
[-] 192.168.50.15 trying...
Exception: Error reading SSH protocol banner[Errno 9] Bad file descriptor
Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/paramiko/transport.py", line 2211, in _check_banner
    buf = self.packetizer.readline(timeout)
  File "/usr/local/lib/python3.5/dist-packages/paramiko/packet.py", line 380, in readline
    buf += self._read_timeout(timeout)
  File "/usr/local/lib/python3.5/dist-packages/paramiko/packet.py", line 607, in _read_timeout
    x = self.__socket.recv(128)
OSError: [Errno 9] Bad file descriptor

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/paramiko/transport.py", line 2039, in run
    self._check_banner()
  File "/usr/local/lib/python3.5/dist-packages/paramiko/transport.py", line 2216, in _check_banner
    "Error reading SSH protocol banner" + str(e)
paramiko.ssh_exception.SSHException: Error reading SSH protocol banner[Errno 9] Bad file descriptor

[-] 192.168.50.16 trying...
[-] 192.168.50.17 trying...
[-] 192.168.50.18 trying...
[-] 192.168.50.19 trying...
[-] 192.168.50.20 trying...

编辑:修改为删除多处理调用。速度较慢但更清晰。

2 个答案:

答案 0 :(得分:0)

这是一个丑陋的解决方法,而不是答案,但这会使错误消失,这很有用。

添加行:

paramiko.util.log_to_file("main_paramiko_log.txt", level = "INFO")

此操作的效果是创建了一个文件,其中包含paramiko的输出。将级别从INFO更改为WARN或ERR很简单。现在,这个特定的错误系列将作为错误打印到日志文件中,并且不再打印到屏幕上。

显然未捕获的错误在paramiko中很常见,a variety of related issues贴在了他们的github上,我在发布之前没有意识到。

答案 1 :(得分:0)

这就是我要做的:

# All Paramiko exceptions except socket ones are subclasses of SSHException
from paramiko.ssh_exception import SSHException

try:
    ...
# Since Python 3.3, socket exceptions are subclasses of OSError
except (SSHException, OSerror) as error:
    ...