通过SCP客户端传输的tar.gz文件导致文件损坏

时间:2019-05-21 05:54:51

标签: python paramiko scp

  1. 通过tar.gz从Linux服务器压缩多个目录
  2. 将压缩的tar.gz文件从服务器下载到Windows计算机。
  3. 尝试通过python的tarfile模块解压缩文件
  4. 进程弹出Empty file(无法解压缩)之一

我需要分割tar文件,因为我需要传输很多小文件(大多数小文件不到一千字节)。因此,我尝试1)将文件从服务器压缩为tar.gz文件2)通过SCP1客户端传输3)从服务器删除tar文件(如果需要)4)在我的python程序中提取下载的文件。 5)创建Excel统计信息。

我从服务器端检查了tar.gz文件,我确定该文件未损坏(我的意思是压缩得很好)。如果我将它们提取到服务器ssh中,则提取得很好,没有任何错误。但是,当我通过程序内部的scp客户端从服务器传输tar.gz文件时,它在上面弹出错误。而且当我使用FileZilla手动传输文件并使用gitbash提取文件时,它没有损坏。

我检查了Internet上的许多线程,他们通常说这是scp二进制模式问题。但是我不确定应该怎么解决这个问题。

我将scpparamiko用于libaray。并且此传输阶段负责scp模块。 (我听说它是​​由paramiko

重新创建的scp客户端模块
import paramiko
from scp import SCPClient
... # (Other class functions)
    def downloadCompressedFile(self, remote_paths, save_path):
        # binarial only
        # remote_paths :: Files to be tared
        # save_path :: Local path to be downloaded
        try:
            print('Compression Targets -->\n{}'.format(', '.join(remote_paths)))
            conn = self.getSSHConnection()
            tar_save_path = '{}/{}.tar.gz'.format(ROOT_TAR_PATH, datetime.now().strftime('%Y%m%d_%H%M%S'))
            obj = [ '-C {} ..'.format(p) for p in remote_paths]
            command = 'tar cvzf {} {}'.format(tar_save_path, ' '.join(obj))
            print('Remote Command -- tar -cvzf {} {}'.format(tar_save_path, ' '.join(obj)))
            conn.exec_command(command=command)
            print('Compressions are done. Downloading files from {} to {}'.format(tar_save_path, save_path))
            with SCPClient(conn.get_transport()) as scp:
                scp.get(remote_path=tar_save_path, local_path=save_path)

        except Exception as e:
            raise Exception(e)
...

它应该传输未损坏的文件。

1 个答案:

答案 0 :(得分:0)

我相信您的代码不会等待tar完成。因此,您下载的文件不完整。

请参见Wait until task is completed on Remote Machine through Python

尝试一下:

stdin, stdout, stderr = client.exec_command(command)
print('Compression started')
stdout.channel.recv_exit_status() # Wait for tar to complete
print('Compression is done. Downloading files from {} to {}'.format(tar_save_path, save_path))