Paramiko连接时挂起

0 投票
1 回答
21 浏览
提问于 2025-04-13 19:54

我正在尝试使用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)

撰写回答