杰瑞科技汇

SecureCRT如何用Python实现自动化脚本?

使用 Python 作为“胶水语言”,通过 SecureCRT 提供的自动化对象模型来控制和管理 SecureCRT 会话。

SecureCRT如何用Python实现自动化脚本?-图1
(图片来源网络,侵删)

核心概念:SecureCRT 对象模型

SecureCRT 将其内部功能暴露给外部的脚本引擎(包括 Python),你可以通过一个根对象 crt 来访问所有其他功能,这个对象模型就像一个家族树:

  • crt (根对象)
    • crt.Session (当前活动的会话)
      • crt.Session.Screen (当前会话的屏幕对象,用于发送命令和读取输出)
    • crt.Sessions (所有已打开的会话集合)
    • crt.Dialog (用于创建和管理对话框)
    • crt.File (用于文件操作)
    • crt.IniFile (用于读取/写入 INI 配置文件)
    • crt.GetOption / crt.SetOption (获取/设置全局选项)

准备工作:安装 Python 环境

  1. 确保 SecureCRT 支持:SecureCRT 从版本 7.0 开始就内置了 Python 脚本支持,并且支持越来越好,请确保你的版本较新。
  2. 安装 Python 解释器
    • SecureCRT 自带了一个基础的 Python 环境,但通常功能有限(可能缺少 requests 等常用库)。
    • 强烈建议在你的系统上安装一个完整的 Python 解释器(例如从 python.org 下载安装),这样可以让你使用丰富的 Python 生态库。
  3. 配置 SecureCRT 使用你的 Python
    • 在 SecureCRT 中,进入 Options -> Global Options...
    • 在左侧导航栏中,展开 Advanced 并选择 Scripting
    • 在右侧的 Python 选项卡下,取消勾选 "Use SecureCRT's embedded Python interpreter"。
    • 在 "Path to Python interpreter" 字段中,填入你安装的 Python 解释器的完整路径,C:\Python39\python.exe (Windows) 或 /usr/bin/python3 (Linux/macOS)。
    • 点击 OK 保存。

第一个脚本:连接并执行命令

这是一个最经典的例子:自动登录到一台交换机,进入特权模式,并显示系统版本信息。

目标

  1. 连接到设备。
  2. 输入用户名和密码。
  3. 进入特权模式。
  4. 执行 show version 命令。
  5. 将输出保存到文件。

脚本示例 (basic_example.py)

SecureCRT如何用Python实现自动化脚本?-图2
(图片来源网络,侵删)
# -*- coding: utf-8 -*-
import os
import time
import crt
# --- 配置信息 ---
# 将 'your_session_name' 替换为你的 SecureCRT 会话名称
SESSION_NAME = "your_session_name" 
# 将 'your_username' 和 'your_password' 替换为你的凭据
USERNAME = "your_username"
PASSWORD = "your_password"
ENABLE_PASSWORD = "your_enable_password" # 如果需要
OUTPUT_FILE = "show_version_output.txt"
def main():
    """
    主函数:连接到会话并执行命令
    """
    # 1. 获取当前活动会话,或者按名称打开一个会话
    # crt.Session.Connect() 会连接到当前标签页的会话
    # 如果需要按名称连接,可以使用 crt.Sessions.New()
    # 这里我们假设脚本是在一个已连接的会话标签页中运行的
    session = crt.Session
    # 2. 获取屏幕对象,用于与设备交互
    screen = session.Screen
    # 3. 等待登录提示出现,然后输入用户名
    # 使用 Expect 方法等待特定字符串出现,超时时间为 10 秒
    screen.WaitForString("login: ", 10)
    screen.Send(USERNAME + "\r") # \r 代表回车
    # 4. 等待密码提示,然后输入密码
    screen.WaitForString("Password: ", 10)
    screen.Send(PASSWORD + "\r")
    # 5. 等待命令行提示符出现
    # 提示符可能因设备而异,这里用通用的 '>' 或 '#' 表示
    # 使用正则表达式匹配更灵活
    screen.WaitForStrings(["#", ">"], 10)
    # 6. 进入特权模式 (如果当前在用户模式)
    if screen.CurrentRow < screen.CurrentRow: # 一个简单的判断逻辑,实际应根据提示符判断
        # 更健壮的判断方式是检查当前行的内容
        #  if ">" in screen.Get(screen.CurrentRow, screen.CurrentRow, 100):
        screen.Send("enable\r")
        screen.WaitForString("Password: ", 10)
        screen.Send(ENABLE_PASSWORD + "\r")
        screen.WaitForString("#", 10) # 等待特权模式提示符
    # 7. 执行 'show version' 命令
    screen.Send("show version\r")
    # 8. 等待命令执行完成
    # 等待新的提示符出现,说明命令已执行完毕
    screen.WaitForString("#", 20)
    # 9. 获取屏幕输出并保存到文件
    # Get() 方法可以获取屏幕上的文本
    # 获取从屏幕顶部到当前光标位置的所有内容
    output = screen.Get(1, 1, screen.CurrentRow, screen.Column)
    # 将输出写入文件
    with open(OUTPUT_FILE, "w", encoding="utf-8") as f:
        f.write(output)
    crt.Dialog.MessageBox(f"命令执行完成,输出已保存到 {os.path.abspath(OUTPUT_FILE)}", "完成")
if __name__ == "__main__":
    main()

如何运行此脚本:

  1. 将上述代码保存为 basic_example.py 文件。
  2. 在 SecureCRT 中,打开一个对应 your_session_name 的会话标签页。
  3. 在 SecureCRT 中,点击 Script -> Run
  4. 浏览并选择你刚刚保存的 basic_example.py 文件,点击 Run

脚本将自动执行,你会在屏幕上看到输入的用户名、密码和命令,最后会弹出一个提示框告诉你脚本运行完毕。


常用对象和方法详解

crt.Screen 对象 (核心交互对象)

这是你最常打交道的对象,用于与远程设备的终端屏幕进行交互。

  • screen.Send(string): 发送字符串到远程设备,记得用 \r\n 作为回车。
    screen.Send("show ip interface brief\r")
  • screen.WaitForString(string, timeout_seconds): 等待屏幕上出现指定的字符串,如果超时,会抛出异常,这是同步脚本的关键。
    screen.WaitForString("# ", 30) # 等待特权模式提示符,最多等30秒
  • screen.WaitForStrings(list_of_strings, timeout_seconds): 等待列表中的任意一个字符串出现。
    # 等待登录提示或密码提示,适用于不同的登录阶段
    screen.WaitForStrings(["login:", "Username:"], 10)
  • screen.Get(start_row, start_col, end_row, end_col): 获取屏幕指定矩形区域内的文本。
    # 获取从第1行第1列到当前光标位置的所有文本
    full_output = screen.Get(1, 1, screen.CurrentRow, screen.Column)
  • screen.CurrentRow / screen.Column: 只读属性,获取当前光标所在的行和列。
  • screen.ReadString(prompt_string, timeout_seconds): 发送一个字符串后,等待并读取回显的响应。
    screen.Send("hostname\r")
    response = screen.ReadString("# ", 5) # 发送hostname命令后,等待提示符并读取响应
  • screen.Synchronous(True): 设置为同步模式,这是强烈推荐的模式,在同步模式下,Send() 操作会等待命令的回显完成,这可以防止你的脚本发送命令过快,导致设备来不及处理,默认情况下可能是异步的,容易出错。

crt.Session 对象

  • crt.Session.Connect(): 连接到当前活动标签页的会话。
  • crt.Session.Disconnect(): 断开当前会话。
  • crt.Session.Config.Get("OptionName"): 获取当前会话的某个配置项的值。
    # 获取当前会话的IP地址
    ip_address = crt.Session.Config.Get("Hostname")

crt.Sessions 对象 (管理多个会话)

  • crt.Sessions.New(path_to_session): 根据会话路径创建一个新的会话连接。
    # 连接到另一个会话
    new_session = crt.Sessions.New("RackServer/Switch01")
    # 切换到新会话的标签页
    new_session.Activate()
  • for session in crt.Sessions:: 遍历所有已打开的会话。
    for s in crt.Sessions:
        print(s.Name) # 打印所有会话的名称

进阶示例:批量配置多台设备

这个脚本会从一个文件中读取设备列表,依次连接到每台设备,执行配置,然后断开连接。

SecureCRT如何用Python实现自动化脚本?-图3
(图片来源网络,侵删)

设备列表文件 (devices.txt)

# 格式: 会话路径,配置命令
192.168.1.10,interface GigabitEthernet0/1
192.168.1.10,no shutdown
192.168.1.10,exit
192.168.1.20,interface GigabitEthernet0/2
192.168.1.20,no shutdown
192.168.1.20,exit

批量配置脚本 (batch_config.py)

# -*- coding: utf-8 -*-
import crt
import time
# --- 配置 ---
DEVICE_LIST_FILE = "devices.txt"
USERNAME = "admin"
PASSWORD = "your_password"
ENABLE_PASSWORD = "your_enable_password"
COMMAND_DELAY = 2 # 每条命令后等待的秒数,确保设备处理完毕
def main():
    """
    主函数:批量配置设备
    """
    try:
        with open(DEVICE_LIST_FILE, "r", encoding="utf-8") as f:
            lines = f.readlines()
    except FileNotFoundError:
        crt.Dialog.MessageBox(f"错误:找不到设备列表文件 {DEVICE_LIST_FILE}", "错误")
        return
    # 设置为同步模式,确保命令发送和接收的顺序性
    crt.Screen.Synchronous = True
    for line in lines:
        line = line.strip()
        if not line or line.startswith('#'):
            continue # 跳过空行和注释
        parts = line.split(',', 1)
        if len(parts) != 2:
            crt.Dialog.MessageBox(f"警告:格式错误,已跳过行: {line}", "警告")
            continue
        session_path, command = parts
        try:
            # 1. 连接到设备
            crt.Session.Connect("/S " + session_path)
            session = crt.Session
            screen = session.Screen
            # 2. 登录流程 (与第一个例子类似)
            screen.WaitForString("login: ", 10)
            screen.Send(USERNAME + "\r")
            screen.WaitForString("Password: ", 10)
            screen.Send(PASSWORD + "\r")
            screen.WaitForStrings(["#", ">"], 10)
            if ">" in screen.Get(screen.CurrentRow, 1, screen.CurrentRow, 10):
                screen.Send("enable\r")
                screen.WaitForString("Password: ", 10)
                screen.Send(ENABLE_PASSWORD + "\r")
                screen.WaitForString("#", 10)
            # 3. 执行配置命令
            crt.Dialog.MessageBox(f"正在为 {session_path} 执行命令: {command}", "执行中")
            screen.Send(command + "\r")
            time.sleep(COMMAND_DELAY) # 简单的等待,确保命令执行
            # 4. 等待命令完成并回到提示符
            screen.WaitForString("#", 10)
            # 5. 断开连接
            session.Disconnect()
            crt.Dialog.MessageBox(f"已成功配置 {session_path} 并断开连接。", "完成")
        except Exception as e:
            crt.Dialog.MessageBox(f"处理 {session_path} 时发生错误: {str(e)}", "错误")
            # 即使出错,也尝试断开连接,防止会话卡死
            if crt.Session.Connected:
                crt.Session.Disconnect()
if __name__ == "__main__":
    main()

调试技巧

  1. 使用 crt.Dialog.MessageBox(): 在脚本的关键位置插入 crt.Dialog.MessageBox("变量X的值是: " + str(x)),可以实时查看变量内容,是调试最简单有效的方法。
  2. 使用 crt.screen.Get() 查看屏幕内容: 如果脚本在 WaitForString 处卡住,很可能是因为等待的字符串没有出现,可以在等待前用 crt.Dialog.MessageBox(screen.Get(1,1,screen.CurrentRow, screen.Column)) 来查看屏幕上实际显示的内容。
  3. Python IDE 调试: 对于复杂的脚本,可以在 VS Code 或 PyCharm 等IDE中设置断点进行调试,这需要你从外部调用脚本,并将 SecureCRT 作为 COM 服务器启动,相对复杂,但对于大型项目非常有效。

使用 Python 脚本自动化 SecureCRT 是一个非常强大的技能,可以极大地提升网络工程师和管理员的工作效率。

  • 入门:从 crt.ScreenSend()WaitForString() 开始,掌握同步模式。
  • 核心:理解并熟练使用 crtcrt.Sessioncrt.Screen 这三个核心对象。
  • 进阶:利用 crt.Sessions 进行批量操作,结合文件 I/O 和 Python 标准库实现复杂自动化流程。
  • 调试:善用 MessageBox 和查看屏幕输出来定位问题。

希望这份详细的指南能帮助你快速上手 SecureCRT Python 脚本编程!

分享:
扫描分享到社交APP
上一篇
下一篇