You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Paramiko执行命令后channel.recv未返回提示符,循环无法终止

问题分析与修复方案

核心问题点

  • 错误判断channel.recv:channel.recv是方法而非属性,if channel.recv:始终为真,无法正确识别数据是否就绪。
  • 重复调用recv导致数据丢失:连续两次调用channel.recv(1024)会读取不同的缓冲区数据,可能使COMMAND_COMPLETED被读取后未被检测到。
  • 固定time.sleep不可靠:依赖固定等待时间应对命令执行延迟,易因网络或服务器性能波动导致逻辑失效。

修正后的代码

import paramiko
import time
import socket

def list_pass(hostname, user):
    # 替换为实际的密码获取逻辑
    return "your_password_here"

hostname = "your_server_hostname"

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
    ssh.connect(hostname, username='xyz', password=list_pass(hostname, 'xyz'))

    command = 'puppet agent -t --no-use_cached_catalog ; echo COMMAND_COMPLETED'

    channel = ssh.invoke_shell()
    # 等待初始提示符就绪
    while not channel.recv_ready():
        time.sleep(0.1)
    channel.send("su -\n")
    
    # 等待密码输入提示
    while True:
        if channel.recv_ready():
            output = channel.recv(1024).decode()
            if "Password:" in output:
                break
        time.sleep(0.1)
    
    channel.send(list_pass(hostname, 'root') + "\n")
    
    # 等待切换root后的提示符(根据实际服务器提示符调整,比如#号)
    while True:
        if channel.recv_ready():
            output = channel.recv(1024).decode()
            if "#" in output:
                break
        time.sleep(0.1)
    
    channel.send(command + '\n')
    
    # 循环读取输出直到找到结束标记
    full_output = ""
    while True:
        if channel.recv_ready():
            chunk = channel.recv(1024).decode()
            full_output += chunk
            print(chunk, end='')
            if "COMMAND_COMPLETED" in full_output:
                break
        time.sleep(0.1)

    channel.close()
    ssh.close()

except paramiko.AuthenticationException:
    print("Authentication failed")
except socket.gaierror:
    print(f"Can't connect to {hostname}. Verify if server exists and it's up.")

关键优化说明

  • 用recv_ready()判断数据就绪:替代固定sleep,高效准确地检测缓冲区是否有数据。
  • 统一收集输出内容:将所有读取到的内容存入full_output,避免多次recv导致数据遗漏,确保结束标记能被正确检测。
  • 基于提示符的流程控制:通过检测Password:和root提示符来判断步骤完成,比固定sleep更可靠。

内容的提问来源于stack exchange,提问作者Pranit Dhumne

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 04:45:15