用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真是太好了!

相关推荐
geovindu10 小时前
CSharp: Observer Pattern
开发语言·后端·观察者模式·设计模式·c#·.netcore·行为模式
萧鼎10 小时前
Python 高性能Web框架神器 FastAPI:自动生成API文、基于Pydant、异步请求处理全搞定
前端·python·fastapi
2601_9622998810 小时前
Linux执行Python脚本方法
linux·python·脚本·解释器·shebang
郝学胜-神的一滴10 小时前
C++11 工程级应用 09:告别无谓拷贝,解锁高性能移动语义
开发语言·数据结构·c++·vscode·软件工程·visual studio
旋生万物11 小时前
量子纠错容错率87%?螺旋拓扑码用“相位保护“给量子比特上保险(附Python)
python·ai编程·量子计算·量子纠错·螺旋计算
用户83562907805111 小时前
使用 Python 设置 Excel 页眉和页脚
后端·python
databook11 小时前
异常值检测与处理方法总结
python·数据挖掘·数据分析
千里码aicood11 小时前
面向智能助理的多轮医疗对话生成系统开发
python
MC皮蛋侠客11 小时前
OPC UA 系列(一):标准全景与 Python 最小闭环——让第一条设备数据流动起来
开发语言·python·opcua
用户37215742613511 小时前
使用 Python 提取 Word 文档中的表格数据
python