Python pexpect sendline()发送文本出现意外空格问题求助
问题分析与解决:pexpect Telnet发送长命令时字符错乱的问题
我之前调试嵌入式设备时也碰到过类似的telnet命令乱码/截断问题,结合你用Python 2.7+pexpect 4.5.0在Ubuntu 16.04虚拟环境下的场景,大概率是以下几个原因导致的:
可能的原因
- Telnet连接的缓冲区/流量控制限制:嵌入式设备的Telnet服务(比如BusyBox自带的轻量telnetd)通常缓冲区较小,当你用
sendline()一次性发送长管道命令时,设备端的接收缓冲区可能来不及处理连续的字节流,导致字符错位或丢失,就出现了xargs变成xar gs的情况。短命令因为字节数少,刚好能被完整接收,所以没问题。 - Pexpect发送速率过快:
sendline()默认是把整段命令加换行一次性推送给底层连接,没有考虑嵌入式设备的处理延迟,导致设备端还没接收完所有字符就开始解析,出现了拆分错误。 - 嵌入式Telnet服务的健壮性问题:部分轻量telnet实现对带特殊字符(管道、参数符)的长命令支持不好,超过一定长度就容易出现解析异常,而且这种问题不会每次都出现,和设备当时的负载、缓冲区状态有关。
解决方法
1. 拆分命令发送,增加延迟
不要一次性发送完整命令,把长命令拆成小块发送,每发一块就加个微小的延迟,给设备端足够的接收时间。示例代码如下:
import time import pexpect # 初始化telnet连接(替换成你的设备IP和端口) telnet = pexpect.spawn('telnet 192.168.1.100 23') telnet.expect('login: ') telnet.sendline('root') telnet.expect('Password: ') telnet.sendline('your_password') telnet.expect('# ') # 拆分长命令发送 cmd = "ls --color=never | grep -v bootimage | xargs -n1 rm -rf" # 按每20个字符拆分,可根据实际情况调整长度 for chunk in [cmd[:20], cmd[20:40], cmd[40:]]: telnet.send(chunk) time.sleep(0.1) # 给设备留接收时间 telnet.sendline('') # 发送换行执行命令 telnet.expect('# ')
2. 调整Pexpect的发送参数
在初始化spawn对象时,设置delaybeforesend参数,让发送前有个小延迟,避免发送速率过快:
telnet = pexpect.spawn('telnet 192.168.1.100 23', delaybeforesend=0.1)
或者在sendline()之后直接加延迟:
telnet.sendline(cmd) time.sleep(0.2)
3. 简化发送的命令长度
把长命令写成设备上的脚本文件,再执行脚本,这样发送的都是短命令,从根源上避免缓冲区问题:
# 先把命令写入临时脚本 telnet.sendline("echo 'ls --color=never | grep -v bootimage | xargs -n1 rm -rf' > /tmp/clean.sh") telnet.expect('# ') # 给脚本加执行权限并执行 telnet.sendline("chmod +x /tmp/clean.sh && /tmp/clean.sh") telnet.expect('# ') # 执行完可删除临时脚本 telnet.sendline("rm /tmp/clean.sh") telnet.expect('# ')
4. 检查设备端的流量控制设置
登录设备后执行stty -a查看是否开启了XON/XOFF流量控制,如果有,关闭它:
stty -ixon -ixoff
这样可以避免因为流量控制触发的发送中断,导致字符丢失。
内容的提问来源于stack exchange,提问作者Henry
相关产品推荐
相关产品推荐

