使用 AsyncSSH 从多台计算机收集文件
Posted
技术标签:
【中文标题】使用 AsyncSSH 从多台计算机收集文件【英文标题】:Use AsyncSSH to collect files from multiple computers 【发布时间】:2020-12-27 04:39:56 【问题描述】:我有一个程序,它将来自多台计算机的各种日志文件收集到客户端计算机上的单个 ZIP 文件中。它目前正在使用 Fabric,我想用 AsyncSSH 重写它,以使所有服务器并行发送它们的文件。
我想要弄清楚的是让文件通过 -- 作为流。我目前基于 Fabric 的代码是:
result = io.BytesIO()
connection.get(remote = path, local = result)
result.seek(0)
return result
当connection
是asyncssh.connect()
的结果时,等价物是什么?
【问题讨论】:
据我所见,asyncssh.connect 返回一个允许您执行命令的对象,例如echo
在示例中。所以只需执行日志文件的cat
。您可以使用 asyncio.gathet 或 .wait 并行触发多个请求(请参阅here)
我的意思是,对于每个源主机,您可以使用result = io.StringIO(await conn.run('cat logfile")
,但同时使用gather
(假设您的日志文件是文本并且不是很大)
我希望有一些通道/流的语义——这样,如果一个特定的文件是 large,它不需要被完全读入客户端的 RAM,但可以被zipfile
读取和压缩——in chunks...
【参考方案1】:
我认为您正在寻找 create_process() 而不是 run()。这将返回一个 SSHClientProcess 对象,该对象具有 stdin/stdout/stderr 类,它们是 SSHReader 和 SSHWriter 对象,其行为类似于 asyncio 的 StreamReader 和 StreamWriter。
或者,如果“connection.get”实际上是在进行 SFTP 文件传输,我认为您想研究在 SFTPClient 对象上使用 open(),而不是 get()。这将为您提供一个可以调用 read() 的文件对象。但是,使用 SFTP,您通常希望同时安排对同一文件的多次读取以提高速度,因此 read() 调用需要一个偏移量和一个大小,而不是将其视为您按顺序访问的流。
【讨论】:
谢谢。你能给出这两个选项的一些示例代码吗? 您可以在asyncssh.readthedocs.io/en/latest/#interactive-input 找到使用 create_process() 的交互式输入示例。不过,我仍然不清楚您到底要做什么,所以很难更具体。我对 Fabric 不是很熟悉——“connection.get”调用到底是做什么的? 如果您所做的与文件传输相关,asyncssh.readthedocs.io/en/latest/#sftp-client 提供了一个示例,说明如何在一次调用中将删除文件检索到本地文件中。如果您想以交互方式从该文件中读取数据,而不是将其写入本地计算机上的磁盘,您可以将“sftp.get”调用替换为“sftp.open”调用,然后调用 read()、seek() ,或对 open() 返回的文件对象的其他此类调用。以上是关于使用 AsyncSSH 从多台计算机收集文件的主要内容,如果未能解决你的问题,请参考以下文章
用于将文件复制到 50 多台远程计算机的 Robocopy 命令
Restful Authentication:允许从多台计算机登录?