You need to enable JavaScript to run this app. 使用paramiko-expect修改OpenWRT路由器root密码未生效问题求助
优惠活动
大模型
产品
解决方案
定价
更多

使用paramiko-expect修改OpenWRT路由器root密码未生效问题求助

问题根本原因

  1. 交互匹配逻辑错误:你调用interact.expect(['.*password.*', '.*password.*'])时,paramiko-expect只会匹配列表中第一个出现的符合规则的内容,也就是Changing password for root这行,此时还没到New password:的输入提示,你提前发送的密码没有被passwd程序正确接收。
  2. 会话提前断开导致变更未落地:两次密码发送完成后,你没有等待passwd命令执行完成、返回shell提示符,就直接退出了SSH上下文,连接被主动关闭,系统还没来得及将密码变更写入/etc/shadow文件,修改自然不生效。你遇到的重定向输出为空的问题也是同样逻辑:ls、ip a执行耗时比pwd长,输出还没写入文件会话就被销毁,只有执行速度最快的pwd能完成写入操作。
  3. 补充:send方法默认不会自动追加换行符,如果你发送的内容没有显式加\n,也会导致输入没有被系统确认接收。

修复代码示例

import paramiko
from paramiko_expect import SSHClientInteraction

# 可选:开启paramiko debug日志排查交互细节
# paramiko.common.logging.basicConfig(level=paramiko.common.DEBUG)

try:
    with paramiko.SSHClient() as ssh:
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.connect('192.168.1.1', 22, 'root', 'old_password')
        
        with SSHClientInteraction(ssh, timeout=10, display=True) as interact:
            # 精准匹配shell提示符再执行命令
            interact.expect(r'.*root@.*#\s*$')
            # 发送命令显式加换行模拟回车操作
            interact.send('passwd\n')
            # 匹配到密码输入提示后再发送密码
            interact.expect(r'New password:\s*$')
            interact.send('new_password\n')
            # 匹配到确认密码提示后再发送二次密码
            interact.expect(r'Retype password:\s*$')
            interact.send('new_password\n')
            # 重点:等待passwd执行完成,返回shell提示符再结束会话
            interact.expect(r'.*root@.*#\s*$')
            # 可选:执行sync确保文件变更写入闪存
            interact.send('sync\n')
            interact.expect(r'.*root@.*#\s*$')

except Exception as e:
    print(f"执行错误: {e}")

通用排查方法

  • 每一步expect执行后打印缓冲区内容interact.current_output,确认匹配到的内容是否符合预期。
  • 执行耗时较长的命令时,增加超时时间,或者主动等待命令执行完成返回提示符后再断开连接。
  • 测试重定向类命令时,可在命令后追加; sync确保输出内容落地到存储。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 13:15:04