Python 2.6基于标准库实现SFTP连接及相关操作技术咨询
使用Python标准库通过用户名密码建立SFTP连接并实现相关功能
由于Python标准库中没有内置的SFTP客户端,我们无法直接通过纯Python代码实现SFTP连接。不过在Unix服务器环境下,系统通常预装了OpenSSH的sftp命令行工具,我们可以通过subprocess模块调用这个工具,间接实现SFTP的各项操作,包括用户名密码认证、目录创建、文件传输以及文件信息获取。
下面是具体的实现方案和代码示例:
核心思路
利用subprocess启动系统sftp进程,通过标准输入输出与该进程交互:
- 发送连接命令并等待密码提示
- 输入密码完成认证
- 发送SFTP命令(mkdir、put、ls等)完成操作
- 解析命令输出获取所需文件信息
完整代码示例
import subprocess import select def sftp_connect(host, port, username, password): """建立SFTP连接""" cmd = ['sftp', '-P', str(port), f"{username}@{host}"] # 启动sftp进程,重定向输入输出 proc = subprocess.Popen( cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True ) # 等待密码提示并输入密码 while True: ready, _, _ = select.select([proc.stdout], [], [], 5) if ready: line = proc.stdout.readline() if not line: raise Exception("连接进程意外终止") if "Password:" in line: # 输入密码 proc.stdin.write(f"{password}\n") proc.stdin.flush() # 检查是否连接成功 next_line = proc.stdout.readline() if "sftp>" in next_line: print("SFTP连接成功") return proc else: raise Exception(f"连接失败: {next_line.strip()}") else: raise Exception("等待密码提示超时") def sftp_mkdir(proc, remote_path): """创建远程目录""" proc.stdin.write(f"mkdir {remote_path}\n") proc.stdin.flush() # 处理命令响应 while True: line = proc.stdout.readline() if not line: break if "sftp>" in line: break if "Couldn't create directory" in line: raise Exception(f"创建目录失败: {line.strip()}") def sftp_put(proc, local_path, remote_path): """上传本地文件到远程服务器""" proc.stdin.write(f"put {local_path} {remote_path}\n") proc.stdin.flush() # 监控上传状态 while True: line = proc.stdout.readline() if not line: break if "sftp>" in line: break if "failed" in line.lower(): raise Exception(f"文件上传失败: {line.strip()}") def sftp_list_files(proc, remote_path): """获取远程目录下文件的时间戳、文件名、大小信息""" proc.stdin.write(f"ls -l {remote_path}\n") proc.stdin.flush() files_info = [] while True: line = proc.stdout.readline() if not line: break if "sftp>" in line: break if line.startswith('total'): continue # 跳过总行数统计行 # 解析ls -l输出 parts = line.split(maxsplit=8) if len(parts) < 9: continue # 跳过无效行 size = int(parts[4]) # 时间部分:月 日 时间/年 timestamp = ' '.join(parts[5:8]) filename = parts[8].strip() files_info.append({ '文件名': filename, '大小(字节)': size, '时间戳': timestamp }) return files_info def sftp_disconnect(proc): """关闭SFTP连接""" proc.stdin.write("quit\n") proc.stdin.flush() proc.wait() if __name__ == "__main__": # 配置参数 SFTP_HOST = "your-sftp-host" SFTP_PORT = 22 SFTP_USER = "your-username" SFTP_PASS = "your-password" REMOTE_DIR = "/remote/target/dir" LOCAL_FILE = "/local/source/file.txt" REMOTE_FILE = f"{REMOTE_DIR}/uploaded_file.txt" try: # 建立连接 sftp_proc = sftp_connect(SFTP_HOST, SFTP_PORT, SFTP_USER, SFTP_PASS) # 创建目录 sftp_mkdir(sftp_proc, REMOTE_DIR) # 上传文件 sftp_put(sftp_proc, LOCAL_FILE, REMOTE_FILE) # 获取文件列表信息 files = sftp_list_files(sftp_proc, REMOTE_DIR) print("\n远程目录文件信息:") for file in files: print(f"文件名: {file['文件名']}, 大小: {file['大小(字节)']}字节, 时间戳: {file['时间戳']}") except Exception as e: print(f"操作出错: {str(e)}") finally: if 'sftp_proc' in locals(): sftp_disconnect(sftp_proc)
注意事项
- 依赖系统工具: 该方案依赖Unix系统预装的OpenSSH
sftp客户端,几乎所有主流Unix/Linux发行版都默认包含。 - 安全性: 密码通过标准输入传递,避免了在命令行暴露,但仍需注意不要在代码中硬编码密码(建议通过环境变量或配置文件读取)。
- 输出解析: 解析
ls -l输出存在一定脆弱性,若SFTP服务器使用非标准格式,可能需要调整解析逻辑。如需更可靠的方式,可以改用sftp的stat命令逐个查询文件详情。 - 错误处理: 示例中的错误处理较为基础,实际使用时可根据需要扩展,处理更多异常场景(如网络中断、权限不足等)。
内容的提问来源于stack exchange,提问作者Vova Lis
相关产品推荐
相关产品推荐

