Skip to main content
 首页 » 编程设计

Python Paramiko 回调之文件传输期间 100% 的重复输出

2025年05月04日9jiqing9006

我正在使用 paramiko 访问网络设备和检索文件。 这工作正常。 我添加了回调函数,以获取每个文件 xfer 的进度。我看到对于每个传输的文件,它似乎都报告了两次它已完成传输。

这是代码。

from __future__ import division 
import paramiko, os 
 
def byte_count(xfer, to_be_xfer): 
    print net_file + " transferred: {0:.0f} %".format((xfer / to_be_xfer) * 100) 
 
path = '/var/log/VPN*' 
cmd = 'file list ' + path 
 
ssh = paramiko.SSHClient() 
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
ssh.connect('10.10.10.10', username = uname, password = psswd) 
stdin, stdout, stderr = ssh.exec_command(cmd) 
 
filelist = stdout.read().splitlines() 
 
ftp = ssh.open_sftp() 
for f in filelist: 
    net_path,net_file=os.path.split(f) 
    ftp.get(f, 'c:\\temp\\' + net_file, callback=byte_count)  
ftp.close() 
 
print '\nExiting..' 
 
ssh.close() 

我得到这个结果......

VPN 转移:14 %
VPN 传输:28 %
VPN 传输:42 %
VPN 传输:56 %
VPN 传输:69 %
VPN 传输:83 %
VPN 传输:97 %
VPN 传输:100 %
VPN 传输:100 %
VPN.0.gz 已转移:100 %
VPN.0.gz 已转移:100 %
VPN.1.gz 转移:44 %
VPN.1.gz 已转移:88 %
VPN.1.gz 已转移:100 %
VPN.1.gz 已转移:100 %
VPN.2.gz 已转移:43 %
VPN.2.gz 已转移:87 %
VPN.2.gz 已转移:100 %
VPN.2.gz 已转移:100 %

为什么最后一行被报告了两次?有办法解决这个问题吗?

请您参考如下方法:

这似乎是 Paramiko 中的一个错误。查看 paramiko v1.12.0 的源代码以及在检查传输是否已完成之前如何调用回调:

def getfo(self, remotepath, fl, callback=None): 
    fr = self.file(remotepath, 'rb') 
    file_size = self.stat(remotepath).st_size 
    fr.prefetch() 
    try: 
        size = 0 
        while True: 
            data = fr.read(32768) 
            fl.write(data) 
            size += len(data) 
            if callback is not None: 
                callback(size, file_size) 
            if len(data) == 0: 
                break 
    finally: 
        fr.close() 
    return size 

在以后的版本中,这是固定的 - http://www.lag.net/paramiko/docs/paramiko.sftp_client-pysrc.html

def get(self, remotepath, localpath, callback=None):  
  fr = self.file(remotepath, 'rb')  
  file_size = self.stat(remotepath).st_size  
  fr.prefetch()  
  try:  
      fl = file(localpath, 'wb')  
      try:  
          size = 0  
          while True:  
              data = fr.read(32768)  
              if len(data) == 0:  
                  break  
              fl.write(data)  
              size += len(data)  
              if callback is not None:  
                  callback(size, file_size)  
      finally:  
          fl.close()  
  finally:  
      fr.close()  

看区别-

if len(data) == 0: 
    break 

在后者的回调之前被调用。 所以你必须要么获得更新版本的 Paramiko,要么忍受这个错误......或者可能使用 Paramiko 代码的补丁:)