当pysftp连接失败时,“‘Connection’对象没有属性‘_sftp_live’”

问题描述 投票:0回答:4

我想在“找不到主机 *** 的主机密钥”时很好地捕获错误,并向最终用户提供适当的消息。我试过这个: import pysftp, paramiko try: with pysftp.Connection('1.2.3.4', username='root', password='') as sftp: sftp.listdir() except paramiko.ssh_exception.SSHException as e: print('SSH error, you need to add the public key of your remote in your local known_hosts file first.', e)

但不幸的是输出不是很好:

SSH error, you need to add the public key of your remote in your local known_hosts file first. No hostkey for host 1.2.3.4 found. Exception ignored in: <function Connection.__del__ at 0x00000000036B6D38> Traceback (most recent call last): File "C:\Python37\lib\site-packages\pysftp\__init__.py", line 1013, in __del__ self.close() File "C:\Python37\lib\site-packages\pysftp\__init__.py", line 784, in close if self._sftp_live: AttributeError: 'Connection' object has no attribute '_sftp_live'

如何很好地避免最后几行/这个“忽略异常”与

try: except:


    

python exception sftp paramiko pysftp
4个回答
15
投票

import pysftp as sftp FTP_HOST = "sftp.abcd.com" FTP_USER = "root" FTP_PASS = "" cnopts = sftp.CnOpts() cnopts.hostkeys = None with sftp.Connection(host=FTP_HOST, username=FTP_USER, password=FTP_PASS, cnopts=cnopts) as sftp: print("Connection succesfully stablished ... ") sftp.cwd('/folder/') # Switch to a remote directory directory_structure = sftp.listdir_attr() # Obtain structure of the remote directory for attr in directory_structure: print(attr.filename, attr)



12
投票

看来附加属性
    self._transport
  1. 也定义得太晚了。
    问题
  2. 可以
  3. 暂时纠正,直到通过子类化pysftp.Connection类来实现永久修复,如下所示:
    
    
    
  4. import pysftp import paramiko class My_Connection(pysftp.Connection): def __init__(self, *args, **kwargs): self._sftp_live = False self._transport = None super().__init__(*args, **kwargs) try: with My_Connection('1.2.3.4', username='root', password='') as sftp: l = sftp.listdir() print(l) except paramiko.ssh_exception.SSHException as e: print('SSH error, you need to add the public key of your remote in your local known_hosts file first.', e)
更新

我无法在桌面上重复此错误。但是,我在代码中看到

pysftp

的源代码,它用

_cnopts
初始化其
self._cnopts = cnopts or CnOpts()
属性,其中
cnopts
pysftp.Connection
构造函数的关键字参数,并且有可能存在
CnOpts
如果未找到主机密钥,构造函数会抛出
HostKeysException
异常,从而导致未设置
_cnopts
属性。
尝试以下更新的代码并让我知道它是否有效:

import pysftp import paramiko class My_Connection(pysftp.Connection): def __init__(self, *args, **kwargs): try: if kwargs.get('cnopts') is None: kwargs['cnopts'] = pysftp.CnOpts() except pysftp.HostKeysException as e: self._init_error = True raise paramiko.ssh_exception.SSHException(str(e)) else: self._init_error = False self._sftp_live = False self._transport = None super().__init__(*args, **kwargs) def __del__(self): if not self._init_error: self.close() try: with My_Connection('1.2.3.4', username='root', password='') as sftp: l = sftp.listdir() print(l) except paramiko.ssh_exception.SSHException as e: print('SSH error, you need to add the public key of your remote in your local known_hosts file first.', e)



12
投票
pysftp.Connection

No hostkey for XXX found
异常中失败时,您总是会遇到这种行为,因为失败的
Connection
对象(它失败了,因此您无法访问它,但它存在于 Python 解释器中)会被 GC 清理,它会删除它,正如您在
here
所看到的,它会首先尝试关闭连接。 我们看到

close()

通过检查
self._sftp_live来检查连接是否处于活动状态。然而,在定义该属性之前,在
Connection
的构造函数中抛出了异常(异常发生在第 132 行
,而 
_sftp_live 是在第 134 行定义的),因此将失败的 Connection
 对象留在状态不一致,因此会出现未捕获的异常。
除了为 pysftp 项目引入一个很好的错误修复之外,我想不出简单的解决方案;)

这对我有用:

import pysftp as sftp FTP_HOST = "**" FTP_USER = "****" FTP_PASS = "rw" port='34343' cnopts = sftp.CnOpts() cnopts.hostkeys = None with sftp.Connection(host=FTP_HOST, username=FTP_USER, password=FTP_PASS, cnopts=cnopts,port=3333) as sftp: print("Connection succesfully stablished ... ") sftp.cwd('jfjksdfjk') # Switch to a remote directory directory_structure = sftp.listdir_attr() sftp.get('fd.csv','C:\\windows\\directory\\your_file_name.csv') for attr in directory_structure: print(attr.filename, attr)#get all directory

0
投票

© www.soinside.com 2019 - 2024. All rights reserved.