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

Paramiko SSH登录成功但无法执行web.txt内多条命令问题求助

Paramiko SSH执行本地文件存储命令失效修复

代码现存问题

  • 主机密钥策略配置错误:SESSION.set_missing_host_key_policy(paramiko.AutoAddPolicy) 传入的是类本身而非实例,会导致主机密钥校验逻辑失效,会话执行异常,正确写法需补充括号实例化:paramiko.AutoAddPolicy()
  • 命令合法性问题:示例中给出的df-g为无效命令,正确磁盘查询命令为df -g,命令与参数之间必须保留空格;单独写入bash命令会触发进程阻塞:exec_command每次调用都会启动独立的非交互式shell进程,执行bash相当于在该进程内启动一个等待用户输入的交互式shell,无后续输入时会一直挂起,无返回结果。
  • 执行逻辑缺陷:循环调用exec_command时,每条命令都运行在独立的临时shell会话中,上一条命令产生的工作目录切换、环境变量修改等状态不会传递到下一条命令,无法满足多命令连续执行的状态依赖需求。
  • 排错信息缺失:原有代码仅读取标准输出流内容,未读取标准错误流信息,命令执行失败时无法拿到报错提示,难以定位问题。
  • 细节逻辑漏洞:原代码连接成功提示的Sucessful存在拼写错误;文件操作未使用上下文管理器,存在文件句柄泄漏风险;未配置连接超时,网络异常时会无限挂起。

修复后完整代码

import paramiko

web_list = []
def create_web_list():
    # 用上下文管理器自动关闭文件
    with open("web.txt", "r", encoding='utf-8') as file:
        for line in file.readlines():
            cmd = line.strip()
            # 过滤空行,避免执行空命令报错
            if cmd:
                web_list.append(cmd)
    return web_list

ip = 'x.x.x.x'
username = 'username'
password = 'password'

def web_device(web_list):
    ssh_session = paramiko.SSHClient()
    # 修复密钥策略实例化问题
    ssh_session.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh_session.connect(
        ip,
        port=22,
        username=username,
        password=password,
        look_for_keys=False,
        allow_agent=False,
        timeout=10  # 增加10秒连接超时,避免无限挂死
    )
    print("Connection Successful")

    # 无状态依赖命令逐条执行逻辑
    for cmd in web_list:
        # 跳过会阻塞的交互式命令
        if cmd.lower() == 'bash':
            print(f"[跳过] 命令`{cmd}`为交互式命令,非交互会话下会触发阻塞,已自动跳过")
            continue
        stdin, stdout, stderr = ssh_session.exec_command(cmd)
        # 读取输出时指定编码,避免乱码
        out_content = stdout.read().decode('utf-8').strip()
        err_content = stderr.read().decode('utf-8').strip()
        
        print(f"\n===== 执行命令: {cmd} =====")
        if out_content:
            print("[正常输出]")
            print(out_content)
        if err_content:
            print("[错误输出]")
            print(err_content)

    # 若需要执行有状态依赖的连续命令(比如先cd到某个目录再执行脚本),注释掉上面的循环,改用交互式shell实现:
    # import time
    # shell = ssh_session.invoke_shell()
    # for cmd in web_list:
    #     shell.send(cmd + '\n')
    # # 等待命令执行完成,可根据服务器响应速度调整等待时间,或通过输出特征匹配判断执行结束
    # time.sleep(3)
    # total_output = shell.recv(65535).decode('utf-8')
    # print(total_output)

    ssh_session.close()

if __name__ == "__main__":
    web_device(create_web_list())

web.txt配置要求

  • 不要写入bash、top这类需要持续交互的命令,非交互SSH会话下这类命令会直接阻塞无返回
  • 命令与参数之间必须保留空格,例如df -g不可写为df-g
  • 每行仅写一条完整命令,不要留多余空行

内容的提问来源于stack exchange,提问作者Ratna Raju

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 07:12:27