用python脚本访问被网关隔离的嵌入式设备

背景

公司一台数据采集设备(下位机)里有两块ARM板,一块做UI显示(兼网关),另一块做实际的数据采集(采集板),下位机采集到数据后,用户需要先通过mobaxterm等ssh客户端连接到网关,然后在网关运行scp命令将数据文件从采集板拷贝到网关,最后再用mobaxterm的ssh browser工具将数据文件拷贝到Windows,非常麻烦,最好能脚本化。

思路

用scp下载文件需要在控制台输入密码,因此要用expect之类的工具,实现自动输入ssh密码的效果

走过的弯路

python的expect实现叫pexpect,可惜pexpect不支持Windows。

python还有一个专门适配Windows的expect实现,叫wexpect,但可能是年久失修,表现很不稳定,在win11上还行,但不支持win10,而我的开发环境是win10

wexpect官方示例代码

python 复制代码
import wexpect
child = wexpect.spawn('cmd.exe')
child.expect('>')
child.sendline('ls')
child.expect('>')
print(child.before)
child.sendline('exit')

官方示例运行异常信息

复制代码
Traceback (most recent call last):
  File "D:/work_dir/DMM/wexpect.py", line 1, in <module>
    import wexpect
  File "D:\work_dir/DMM\wexpect.py", line 2, in <module>
    child = wexpect.spawn('cmd.exe')
AttributeError: partially initialized module 'wexpect' from 'D:\work_dir/DMM\wexpect.py' has no attribute 'spawn' (most likely due to a circular import)

wexpect版本4.0.0,python版本3.14.2,希望解决上述问题的朋友可以将方法分享出来。

求助豆包

在上面2种expect上花了很长时间没有进展,无奈询问豆包

复制代码
怎样在Windows上实现自动输入ssh密码的python脚本?

然后豆包给了我详尽的回答,其中包括2种路线,一种是paramiko,另一种是expect,且推荐第一种。

我试了豆包的expect脚本,发现也跑不起来,不过报错信息没我那么初级,豆包的wexpect脚本

python 复制代码
import wexpect

def ssh_with_wexpect(host, user, pwd):
    cmd = f"ssh {user}@{host}"
    # 启动ssh进程
    child = wexpect.spawn(cmd)
    try:
        # 匹配密码提示,自动输入
        child.expect("password:", timeout=10)
        child.sendline(pwd)
        # 匹配登录成功提示符(根据你的服务器改,比如 # $ >)
        child.expect(r"[#$>]", timeout=5)
        print("登录成功,当前终端输出:")
        print(child.before.decode())

        # 执行远程命令
        child.sendline("df -h")
        child.expect(r"[#$>]")
        print("df -h 输出:\n", child.before.decode())

    except wexpect.ExpectTimeout:
        print("等待输入超时,密码错误或无法连接")
    finally:
        child.close()

if __name__ == "__main__":
    ssh_with_wexpect("192.168.100.30", "root", "root")

脚本执行异常信息:

复制代码
Traceback (most recent call last):
  File "D:\whp\get_adc2.py", line 9, in ssh_with_wexpect
    child.expect("password:", timeout=10)
  File "C:\Users\whp\AppData\Local\Python\pythoncore-3.14-64\Lib\site-packages\wexpect\host.py", line 732, in expect
    return self.expect_list(compiled_pattern_list, timeout, searchwindowsize)
  File "C:\Users\whp\AppData\Local\Python\pythoncore-3.14-64\Lib\site-packages\wexpect\host.py", line 745, in expect_list
    return self.expect_loop(searcher_re(pattern_list), timeout, searchwindowsize)
  File "C:\Users\whp\AppData\Local\Python\pythoncore-3.14-64\Lib\site-packages\wexpect\host.py", line 806, in expect_loop
    raise EOF('EOF flag has been raised.')
wexpect.wexpect_util.EOF: EOF flag has been raised.

无奈尝试paramiko方法

正解:paramiko

试了下,paramiko版脚本可以正常完成ssh访问!

结合自己的需求对豆包代码做了调整,自己的需求终于实现了,代码贴出来

python 复制代码
import time
import paramiko

if __name__ == "__main__":
    # 配置你的服务器信息
    HOST = "192.168.100.30"
    PORT = 22
    USER = "root"
    PWD = "root"

    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(HOST, PORT, USER, PWD)
    sftp = ssh.open_sftp()

    # 打开交互式shell
    shell = ssh.invoke_shell()
    time.sleep(0.3)
    print(shell.recv(2048).decode())

    # 发送第一条命令
    shell.send("scp root@192.168.1.10:/var/log/messages .\n")
    time.sleep(2.0)
    print(shell.recv(1024).decode())
    shell.send("root\n")
    time.sleep(2.0)
    print(shell.recv(1024).decode())

    # 发送第二条
    sftp.get("messages", "syslog")
    time.sleep(2.0)
    print(shell.recv(1024).decode())

    ssh.close()

注意:paramiko不仅实现了ssh协议,还实现了控制台shell的功能(expect的核心特性),因此可以通过给网关发送scp命令和ssh密码,实现在网关上也自动化ssh登录的效果。

总结

要想在Windows上用expect,只能安装Active Tcl,不仅要学习TCL语言,而且该发行版还是收费的,两相对比,paramiko真是太好了!

相关推荐
老白干2 小时前
jjwt 0.9.1 在 JDK 11+ 上的两个“坑”与完整解决方案
java·python·log4j
笨鸟先飞,勤能补拙8 小时前
AI 赋能网络安全:技术全景、成熟度评估与实战案例
人工智能·python·安全·web安全·网络安全·sqlite·github
微学AI9 小时前
一根针指向所有方向:挂谷猜想对 LLM Agent 技能-记忆架构的启示
开发语言·人工智能·架构·挂谷猜想
长和信泰光伏储能9 小时前
京津冀光伏发电:绿色能源的未来之路
python·能源
豆瓣鸡9 小时前
算法日记 - Day3
java·开发语言·算法
浦信仿真大讲堂9 小时前
从重复操作到自动化闭环:如何让 CST 与 Python 真正协同起来
python·自动化·cst·仿真软件·达索软件
韭菜炒鸡肝天10 小时前
VTK开发笔记(一):VTK介绍,Qt..+VSx+VTK.编译
开发语言·笔记·qt
Gu Gu Study10 小时前
ScoutLoop开放域深度研究引擎(agent的初步设计想法)
人工智能·python
Aaron - Wistron10 小时前
Web API C# (Furion版)带 单元测试
开发语言·后端·c#
卷无止境11 小时前
写代码这件事,到底该讲究点什么?
后端·python