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

相关推荐
酷酷的身影1 小时前
Drivers/LedManager.cs
开发语言·php
小樱花的樱花1 小时前
Linux 线程的创建
linux·c语言·开发语言
GEO_ai_zhijian1 小时前
饮料生产线质量检测系统供应商哪家强
大数据·python
xiaoshuaishuai82 小时前
C# AI实现PR处理、单元测试
开发语言·c#·log4j
C++、Java和Python的菜鸟2 小时前
第7章 Java高级技术
java·开发语言
LONGZHIQIN2 小时前
C#基础复习笔记
开发语言·笔记·c#
可靠的仙人掌2 小时前
SAC(Soft Actor-Critic)算法底座
开发语言·算法·php
量化吞吐机2 小时前
近期量化工具怎么选,先看规则流程能否承接
人工智能·python
学逆向的2 小时前
汇编——数据存储模式
开发语言·汇编·网络安全