Paramiko SFTP put命令执行阻塞问题求助
SFTP上传文件在Linux环境阻塞问题排查与解决
问题现象
通过SFTP向远程服务器传输zip文件,Windows环境下网络正常时可顺利传输,但Linux环境下脚本持续阻塞。日志显示传输进度已达到100%并打印了finished,但脚本未执行到print("exited"),始终卡住。尝试在上传完成时抛出异常终止,未解决问题。
日志信息
Jul 28 10:24:40 igt22-dev mqtt.sh[1353]: 46.21875 46.258296966552734 Jul 28 10:24:40 igt22-dev mqtt.sh[1353]: 46.25 46.258296966552734 Jul 28 10:24:40 igt22-dev mqtt.sh[1353]: 46.258296966552734 46.258296966552734 Jul 28 10:24:40 igt22-dev mqtt.sh[1353]: finished
相关代码
ftp_client = server_client.open_sftp() source = "/usr/local/bin/log_history.zip" destination = "/home/ubuntu/log_history.zip" def callback_fun(current, maximum): print(current / 1048576, maximum / 1048576) sys.stdout.flush() if current == maximum: print("finished") sys.stdout.flush() raise Exception("finished") ftp_client.put(source, destination, callback=callback_fun) ftp_client.close() print("exited") sys.stdout.flush()
问题分析与解决方法
移除回调中的异常抛出
Paramiko的put方法回调仅用于进度通知,抛出的异常会被内部捕获处理,无法终止传输流程,反而可能导致客户端内部状态异常。删除回调里的raise Exception("finished")语句。使用上下文管理器确保SFTP客户端正确释放
改用with语句管理SFTP客户端,避免手动关闭时因阻塞导致资源未释放:
with server_client.open_sftp() as ftp_client: source = "/usr/local/bin/log_history.zip" destination = "/home/ubuntu/log_history.zip" def callback_fun(current, maximum): print(current / 1048576, maximum / 1048576) sys.stdout.flush() if current == maximum: print("finished") sys.stdout.flush() ftp_client.put(source, destination, callback=callback_fun, confirm=True) print("exited") sys.stdout.flush()
显式启用传输确认
在put方法中设置confirm=True(默认已开启,但显式设置可确保传输完成后校验文件完整性),避免因远程服务器未返回确认导致阻塞。检查Paramiko版本兼容性
对比Windows和Linux环境下的Paramiko版本,若版本差异较大,升级到最新稳定版(pip install --upgrade paramiko),修复可能存在的平台兼容性问题。排查远程服务器端问题
- 查看远程SFTP服务日志,确认文件写入完成后是否存在权限、锁或磁盘IO阻塞。
- 检查远程服务器目标目录的写入权限,确保用户有足够权限完成文件写入。
- 测试小文件传输并调整缓冲区
尝试传输小文件验证是否同样阻塞,若小文件正常,说明可能是大文件传输时的缓冲区或IO问题,可尝试调整Paramiko的SFTP传输缓冲区大小:
ftp_client = server_client.open_sftp() ftp_client.chunk_size = 32768 # 调整为32KB,默认可能是16KB # 后续传输代码不变
内容的提问来源于stack exchange,提问作者L1RG0
相关产品推荐
相关产品推荐

