You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Expect脚本屏蔽Telnet登录成功前的终端输出

Expect Telnet自动登录屏蔽前置输出问题修复

初始测试脚本

需求为在Bash环境中调用Expect实现自动登录IP为192.168.1.11的Telnet服务,执行ls命令,要求屏蔽Telnet成功登录前输出到本地终端的内容,初始测试脚本如下:

expect << EOS
    spawn telnet 192.168.1.11
    expect "login:"
    send "root\r"
    expect "#"
    send "ls\r"
    expect "#"
    send "exit\r"
    expect eof
EOS

直接执行上述脚本会完整输出Telnet连接过程、登录提示、命令执行回显等全部内容,测试过程中遇到三类典型问题:

  • 直接在spawn指令前添加log_user 0;配置,会导致登录成功后ls等命令的输出也被全部屏蔽,不符合需求
  • 调整log_user开关位置,在发送ls命令前开启log_user、匹配到命令提示符后关闭log_user,仍无法屏蔽ls命令自身的回显行
  • 尝试通过正则规则expect -re "$command\r\n(.+)\r\n$prompt"捕获命令执行结果时,出现匹配超时、无法正确读取$expect_out(1,string)缓存中命令输出的问题,即使将变量传参的命令替换为硬编码pwd仍无法正常获取返回结果,当前使用Expect版本为5.45.3

问题原因与修复方案

1. log_user全局屏蔽问题

log_user 0会直接关闭所有spawn进程输出回显到当前终端的通道,不会自动区分登录阶段和命令执行阶段,需要在匹配到登录成功的Shell提示符(即脚本中第一次匹配到#的节点)之后再执行log_user 1开启输出,即可保证登录前的连接过程、登录提示全部被屏蔽,登录后的内容正常输出。

2. 命令自身回显无法屏蔽问题

Telnet服务默认开启终端行回显,发送的命令字符串会被Telnet服务端先回显一行再输出执行结果,仅靠log_user开关无法过滤这行回显。解决方法是在发送命令后,先匹配命令自身的回显内容丢弃,再等待命令提示符,同时捕获中间的输出内容。

3. 正则匹配命令输出超时问题

Expect 5.45.3版本的正则引擎本身不存在\r匹配缺陷,之前捕获失败的核心原因是没有提前消费掉缓冲区里的命令回显行,导致正则匹配的起始位置偏移,最终触发超时。同时Expect正则默认是贪婪匹配,不同Telnet服务端输出的换行符可能是\r\n或者单独\r,提示符前可能存在多余的空白字符,硬编码的\r\n分隔规则很容易匹配失败。编写匹配规则时需要先丢弃命令回显,再兼容不同换行格式,必要时可通过匹配配置降低规则敏感度。

修正后可直接运行的脚本

expect << EOS
    # 登录阶段关闭所有输出
    log_user 0
    spawn telnet 192.168.1.11
    expect "login:"
    send "root\r"
    # 匹配到登录成功的Shell提示符后,开启输出
    expect "#"
    log_user 1

    # 执行ls命令,先过滤命令自身回显
    send "ls\r"
    # 先匹配丢弃ls命令的回显行
    expect -re "ls\r\n"
    # 捕获命令输出直到遇到提示符,兼容\r、\r\n换行格式
    expect -re "(.+)\r?\n.*# "
    # 如需获取命令输出可读取$expect_out(1,string),此处直接让输出正常打印即可

    send "exit\r"
    expect eof
EOS

注意:如果实际环境中Shell提示符不是# (比如带主机名、路径的自定义提示符),需要将匹配规则中的# 替换为实际的提示符特征字符串,避免匹配失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 04:57:42