如何用Python Paramiko获取服务器响应?执行apt命令遇无输出问题
问题分析与解决
核心错误点
- 会话通道不连续:每次调用
exec_command都会新建独立的SSH通道,你后续发送的Y\n和回车是在全新通道里执行,和之前的apt upgrade进程完全无关,自然得不到响应。 - 依赖固定延迟不可靠:
time.sleep()无法精准判断命令执行状态,既不能保证命令完成,也解决不了会话上下文断裂的问题。
解决方案一:使用apt非交互式参数(推荐)
直接给apt upgrade加上非交互式参数,跳过手动确认环节,这是服务器管理的常规做法:
import paramiko host = 'host' user = 'root' secret = 'secret' port = 22 client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect(hostname=host, username=user, password=secret, port=port) # 执行apt update stdin, stdout, stderr = client.exec_command("apt update -y") data = stdout.read() + stderr.read() print(data.decode()) # 执行非交互式apt upgrade stdin, stdout, stderr = client.exec_command("apt upgrade -y") data = stdout.read() + stderr.read() print(data.decode()) client.close()
参数说明:
-y:自动对所有确认提示回答"yes",无需手动输入。
解决方案二:使用交互式会话(适合必须手动交互的场景)
如果一定要模拟交互式输入,需要用invoke_shell()创建持续的会话通道,在同一个通道内发送所有命令和交互输入:
import paramiko import time host = 'host' user = 'root' secret = 'secret' port = 22 client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect(hostname=host, username=user, password=secret, port=port) # 创建交互式shell通道 shell = client.invoke_shell() shell.settimeout(30) # 发送apt update命令 shell.send("apt update\n") time.sleep(3) print(shell.recv(65535).decode()) # 发送apt upgrade命令 shell.send("apt upgrade\n") time.sleep(5) # 发送确认输入Y shell.send("Y\n") # 等待升级过程(实际可通过读取输出关键词判断完成时机,替代固定sleep) time.sleep(60) print(shell.recv(65535).decode()) client.close()
注意:实际使用中建议通过读取shell输出的特定关键词(比如"Do you want to continue?")来触发交互输入,替代固定延迟,提升准确性。
内容的提问来源于stack exchange,提问作者Katerina_GG
相关产品推荐
相关产品推荐

