使用Paramiko实现SSH/SFTP自动化:添加删除命令后代码异常
问题原因分析
你遇到的问题其实很直观:在执行删除文件的命令前,你已经提前关闭了SSH连接!原代码里,执行完tcpdump后立刻调用了ssh.close(),把SSH会话直接关掉了,之后再想用同一个ssh对象执行rm命令,肯定会报错——因为连接早就断开了。
另外还有个小优化点:你完全没必要单独创建SFTP的Transport连接,直接从已有的SSH会话就能生成SFTP客户端,这样代码更简洁,还能复用连接资源。
修复后的完整代码
import paramiko from getpass import getpass # 1. 获取登录凭据 host = input("Host: ") user = input("User: ") port = 22 password = getpass("Password: ") # 2. 建立SSH连接(全程复用这个连接,不要提前关闭) ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: ssh.connect(host, port=port, username=user, password=password) # 3. 执行tcpdump命令抓包 print("开始执行tcpdump抓包...") stdin, stdout, stderr = ssh.exec_command('timeout 10 tcpdump port 5060 -nnv -s 0 -w testtrace.pcap') # 等待命令执行完成 stdout.channel.recv_exit_status() print("tcpdump抓包完成") # 4. 通过已有的SSH会话创建SFTP客户端,不用单独建Transport sftp = ssh.open_sftp() print("开始下载文件...") remote_filepath = '/root/testtrace.pcap' local_filepath = 'C:\\Users\\******\\Desktop\\python\\testtrace.pcap' sftp.get(remote_filepath, local_filepath) sftp.close() # 先关闭SFTP连接 print("文件下载完成") # 5. 执行删除远程文件的命令(此时SSH连接还在) print("开始删除远程文件...") stdin, stdout, stderr = ssh.exec_command('rm -f testtrace.pcap') stdout.channel.recv_exit_status() # 可以检查下删除是否成功 error_msg = stderr.read().decode() if error_msg: print(f"删除文件时出错: {error_msg}") else: print("远程文件删除成功") finally: # 6. 最后统一关闭SSH连接 ssh.close() print("SSH连接已关闭")
关键修复点
- 复用SSH连接:全程只用一个SSH会话,直到抓包、下载、删除所有操作都完成后再关闭,避免连接断开后无法执行后续命令
- 简化SFTP创建:用
ssh.open_sftp()替代单独创建Transport,代码更简洁,还能复用已有的连接会话 - 添加状态提示:方便你跟踪每个步骤的执行情况,排查问题更方便
- 异常安全框架:用
try...finally保证即使中间步骤出错,SSH连接也能被正确关闭,避免资源泄漏
内容的提问来源于stack exchange,提问作者Eric Praline
相关产品推荐
相关产品推荐

