def download():
if os.path.exists( dst_dir_path ) == False:
logger.error( "Cannot access destination folder %s. Please check path and permissions. " % ( dst_dir_path ))
return 1
elif os.path.isdir( dst_dir_path ) == False:
logger.error( "%s is not a folder. Please check path. " % ( dst_dir_path ))
return 1
file_list = None
#transport = paramiko.Transport(( hostname, port))
paramiko.util.log_to_file('paramiko.log')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#transport
try:
ssh.connect( hostname, username=username, password=password, timeout=5.0)
#transport.connect(username=username, password=password )
except Exception, err:
logger.error( "Failed to connect to the remote server. Reason: %s" % ( str(err) ) )
return 1
try:
#sftp = paramiko.SFTPClient.from_transport(transport)
sftp = ssh.open_sftp()
except Exception, err:
logger.error( "Failed to start SFTP session from connection to %s. Check that SFTP service is running and available. Reason: %s" % ( hostname, str(err) ))
return 1
try:
sftp.chdir(src_dir_path)
#file_list = sftp.listdir(path="%s" % ( src_dir_path ) )
file_list = sftp.listdir()
except Exception, err:
logger.error( "Failed to list files in folder %s. Please check path and permissions. Reason: %s" % ( src_dir_path, str(err) ))
return 1
match_text = re.compile( file_mask )
download_count = 0
for file in file_list:
# Here is an item name... but is it a file or directory?
#logger.info( "Downloading file %s." % ( file ) )
if not re.match( file_mask, file ):
continue
else:
logger.info( "File \"%s\" name matched file mask \"%s\". matches %s.Processing file..." % ( file, file_mask, (match_text.match( file_mask ) ) ) )
src_file_path = "./%s" % ( file )
dst_file_path = "/".join( [ dst_dir_path, file] )
retry_count = 0
while True:
try:
logger.info( "Downloading file %s to %s." % ( file, dst_file_path ) )
#sftp.get( file, dst_file_path, callback=printTotals ) #sftp.get( remote file, local file )
sftp.get( file, dst_file_path) #sftp.get( remote file, local file )
logger.info( "Successfully downloaded file %s to %s." % ( file, dst_file_path ) )
download_count += 1
break
except Exception, err:
if retry_count == retry_threshold:
logger.error( "Failed to download %s to %s. Reason: %s." % ( file, dst_file_path, str(err) ) )
sftp.close()
#transport.close()
return 1
else:
logger.error( "Failed to download %s to %s. Reason: %s." % ( file, dst_file_path, str(err) ) )
retry_count +=1
sftp.close()
transport.close()
logger.info( "%d files downloaded." % ( download_count ) )
return 0
当我运行以下函数时,它会下载源文件大约 3 分钟,然后关闭会话,即使只下载了 1-1.6GB 文件的 38-41MB(不定)。
从 Paramiko 日志文件中,看起来 SSh 连接在 SFTP 会话关闭时保持打开状态:
hmac-sha1', 'hmac-sha1-96', 'hmac-md5', 'hmac-md5-96', 'umac-64@openssh.com'] 服务器mac:['hmac-sha1', 'hmac- sha1-96', 'hmac-md5', 'hmac-md5-96', 'umac-64@openssh.com'] 客户端压缩:['zlib@openssh.com', 'zlib', 'none'] 服务器compress:['zlib@openssh.com', 'zlib', 'none'] 客户端 lang:[''] 服务器 lang:[''] kex 跟随?假 DEB [20120913-10:05:07.421] thr=1 paramiko.transport:密码同意:local=aes128-ctr,remote=aes128-ctr DEB [20120913-10:05:07.421] thr=1 paramiko.transport:使用 kex diffie-hellman-group1-sha1;服务器密钥类型 ssh-dss;密码:本地 aes128-ctr,远程 aes128-ctr;mac:本地 hmac-sha1,远程 hmac-sha1;压缩:本地无,远程无 DEB [20120913-10:05:07。625] thr=1 paramiko.transport: 切换到新密钥... INF [20120913-10:05:10.374] thr=2 paramiko.transport.sftp: [chan 1] sftp 会话关闭。DEB [20120913-10:05:10.388] thr=2 paramiko.transport: [chan 1] EOF 发送 (1)
此后,脚本退出并出现此异常(来自 sftp.get() try/except 块)
资源不足,无法完成请求
系统本身有千兆字节的可用磁盘空间,所以这不是问题。
parakmiko 失败的相同传输在 FileZilla 和我几年前编写的用于 SFTP 传输的 Java 应用程序中运行良好。所以我认为这是 paramiko 的问题。
它在 Windows XP 和 Windows Server 2003 上运行。
我已经尝试修补 Paramko 1.17 以便它更频繁地刷新密钥,但传输仍然会引发异常。Python 2.7.3 Paramiko 1.7 与补丁 Windows 2003 Sevfer
想法?
附加信息:它在 Windows XP SP3 和 Windows 2003 服务器上失败,完全相同的行为和错误消息。sys.version 信息 Window XP Workstation: '2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)]' Windows 2003 Server: '2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)]' 我修补了 packet.py 文件以减少密钥更新之间的时间。它对 sftp.get() 的行为没有影响。