如何使用paramiko查看(日志)文件传输进度?

19
我正在使用Paramiko的SFTPClient在主机之间传输文件。我希望我的脚本能够打印文件传输进度,类似于使用scp时看到的输出。
$ scp my_file user@host

user@host password: 

my_file                          100%  816KB 815.8KB/s   00:00

$

有什么想法吗?

提前谢谢。

2个回答

32

使用put函数的可选回调参数,像这样:

def printTotals(transferred, toBeTransferred):
    print "Transferred: {0}\tOut of: {1}".format(transferred, toBeTransferred)

sftp.put("myfile","myRemoteFile",callback=printTotals)

“Out of”可能比“Still to send”更好,因为最后的金额不会改变。 - Dss
@dss 是这样吗?已经过了几年,我不记得 toBeTransferred 数字是总数还是余数了。 - Spencer Rathbun
@SpencerRathbun 嗯,看起来是这样。这是我的打印输出:已传输:205979648 / 263659867 已传输:206012416 / 263659867 已传输:206045184 / 263659867 已传输:206077952 / 263659867 已传输:206110720 / 263659867 已传输:206143488 / 263659867 已传输:206176256 / 263659867第二个数字从未改变,所以我将其更改为“Out of:”。 - Dss

1

请看@Spencer的回答-这是正确的。以下是一些针对2021 PEPs规范的小修改和取模运算,以便仅在每个x MB(或KB、GB)更新输出。

import logging, enum
from paramiko import SSHClient

class SIZE_UNIT(enum.Enum):
   BYTES = 1
   KB = 2
   MB = 3
   GB = 4

def convert_unit(size_in_bytes: int, unit: SIZE_UNIT):
    """Convert the size from bytes to 
    other units like KB, MB or GB
    """
    if unit == SIZE_UNIT.KB:
        return size_in_bytes/1024
    elif unit == SIZE_UNIT.MB:
        return size_in_bytes/(1024*1024)
    elif unit == SIZE_UNIT.GB:
        return size_in_bytes/(1024*1024*1024)
    else:
        return size_in_bytes
        
def progress(transferred: int, tobe_transferred: int):
    """Return progress every 50 MB"""
    if convert_unit(transferred, SIZE_UNIT.MB) % 50 != 0:
        return
    logging.getLogger().info(
        f"Transferred: "
        f"{convert_unit(transferred, SIZE_UNIT.GB):.2f}GB \t"
        f"out of: {convert_unit(tobe_transferred, SIZE_UNIT.GB):.2f}"
        f"GB")

client = SSHClient()
client.connect(...)
sftp = client.open_sftp()
sftp.get(remotepath, localpath, callback=progress)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接