Paramiko连接时挂起
我正在尝试使用paramiko将文件上传到远程的EC2服务器。
我的app.py主要处理tkinter的图形界面,它导入了一个自定义的lib.file_handler模块来处理一些功能。这个file_handler又导入了我的lib.ssh_handler.py模块。这个模块里有一个类,用来处理我的ssh请求。如果我在ssh_handler.py模块里的if __name__ == '__main__':
部分测试这个类,它是可以正常工作的。我知道这是因为在导入的模块中出现了额外线程的问题,但我不知道怎么解决,因为这个模块在我的应用中层级很深。这个讨论建议在导入时不要调用connect(),但我觉得我并没有这样做,因为我必须在使用之前先在lib.file_handler.py中初始化这个类。我并不想一直保持与远程服务器的连接,只在我想上传文件的时候才需要,所以我不想在app.py中使用paramiko.connect()。
问题104自2012年以来一直没有解决,但py3compat似乎不再是这个模块的一部分了。
如果有人能提供解决这个线程问题的方法,或者推荐一个好的paramiko替代品,我将非常感激。
file_handler.py
from lib.ssh_handler import ssh_Handler
ssh = ssh_Handler()
ssh = ssh.upload_files()
ssh_hanlder.py
import paramiko
import lib.Secrets as Secrets
class ssh_Handler():
"""Handle interactions with a remote server"""
def __init__(self, hostname=Secrets.hostname, user=Secrets.ssh_user, ssh_key=Secrets.ssh_key):
self.ssh = paramiko.SSHClient()
self.ssh.load_host_keys(os.path.expanduser(os.path.join("~", ".ssh", "known_hosts")))
self.ssh.connect(hostname=hostname, port=22, username=user, key_filename=ssh_key, allow_agent=False)
self.storage_folder = '/path/to/storage'
03-18 14:02 paramiko.transport DEBUG starting thread (client mode): 0xe42de650
03-18 14:02 paramiko.transport DEBUG Local version/idstring: SSH-2.0-paramiko_3.4.0
03-18 14:02 paramiko.transport DEBUG Remote version/idstring: SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.6
03-18 14:02 paramiko.transport INFO Connected (version 2.0, client OpenSSH_8.9p1)
1 个回答
0
我最后放弃了Paramiko,改用了asyncssh。下面是我工作的代码。这也让我不需要再写一个递归上传的函数。
import asyncio
import asyncssh
async def upload_directory(local_folder,
remote_folder=None,
hostname=Secrets.hostname,
user=Secrets.ssh_user,
ssh_key=Secrets.ssh_key):
if remote_folder is None:
remote_folder = 'folder/to/storage'
async with asyncssh.connect(host=hostname,
username=user,
client_keys=ssh_key,
port=22) as conn:
async with conn.start_sftp_client() as sftp:
await sftp.put(localpaths=local_folder,
remotepath=remote_folder,
recurse=True)
try:
local_path = 'path/to/directory'
asyncio.get_event_loop().run_until_complete(upload_directory(local_path))
except (OSError, asyncssh.Error) as error:
print(error)