BeRightBack
BeRightBack

Reputation: 228

Python telnetlib getting strange escape characters

I'm using telnetlib to connect to device and send some commands over
Everything seems to work fine, but when I try to read response after sending command, command text gets back in wierd format with lot of escape characters

To demonstrate
I connect to device

self.terminal = telnetlib.Telnet(device, port)

I send command (and it gets executed as expected)

self.terminal.write(b'config\r\n')

And then read response

telnetResponse = self.terminal.read_until(b'(Config)#', self.telnetTimeout)

Response I get is my command in some wierd encoding with lot of escape characters and then the rest of response that is normal

b'\x1b7c\x1b8\x1b[1C\x1b7o\x1b8\x1b[1C\x1b7n\x1b8\x1b[1C\x1b7f\x1b8\x1b[1C\x1b7i\x1b8\x1b[1C\x1b7g\x1b8\x1b[1C\n\rmydevice(Config)#'

Everything I get back from read_until is perfectly normal with no escape characters and strange encoding except commands I sent, even when I send command that returns some kind of response, everything is readable but my command
Tried encoding and decoding result in any way I could think of, but encoding it just produces different kind of junk

mydevice#7c8[1C7o8[1C7n8[1C7f8[1C7i8[1C7g8[1C

I'm using Python 3.11.5 on Ubuntu in WSL

Distributor ID: Ubuntu Description: Ubuntu 22.04.1 LTS Release: 22.04 Codename: jammy

Even tried with older versions of pyhton (3.9) but nothing changed

Upvotes: 1

Views: 160

Answers (2)

BeRightBack
BeRightBack

Reputation: 228

In absence of better idea I ended up doing my initial idea, regexing all escape characters from response

ansi_regex = b'\x1b(' \
             b'(\[\??\d+[hl])|' \
             b'([=<>a-kzNM78])|' \
             b'([\(\)][a-b0-2])|' \
             b'(\[\d{0,2}[ma-dgkjqi])|' \
             b'(\[\d+;\d+[hfy]?)|' \
             b'(\[;?[hf])|' \
             b'(#[3-68])|' \
             b'([01356]n)|' \
             b'(O[mlnp-z]?)|' \
             b'(/Z)|' \
             b'(\d+)|' \
             b'(\[\?\d;\d0c)|' \
             b'(\d;\dR))'
ansi_escape = re.compile(ansi_regex, flags=re.IGNORECASE)
communication = ansi_escape.sub(b'', communication)

It produces output as expected, at least in examples I have for now

Upvotes: 0

Karo
Karo

Reputation: 140

This can happen becauseof the way the remote device interprets and echoes back the command. Since you know the command you sent, you can strip it from the response string. For example:

command = b'config\r\n'
telnetResponse = self.terminal.read_until(b'(Config)#', self.telnetTimeout)

# Remove echoed command from response
telnetResponse = telnetResponse[len(command):]

After removing the echoed command using the modified code, your telnetResponse variable result in:

Setting up configuration...
Configuration complete.
(Config)#

Referring to your comment:


import re

# Initialize a list to store executed commands
executed_commands = []

# Function to send a command and capture the response
def send_command(command):
    self.terminal.write(command)
    executed_commands.append(command.decode('utf-8'))  # Store the executed command as a string

# Example usage:
send_command(b'config\r\n')
telnetResponse = self.terminal.read_until(b'(Config)#', self.telnetTimeout)

# Convert the response to a string
response_text = telnetResponse.decode('utf-8')

# Use regular expressions to remove the echoed command, taking into account any format
for cmd in executed_commands:
    response_text = re.sub(rf'^.*?{re.escape(cmd.decode("utf-8"))}', '', response_text, flags=re.DOTALL)

# Print the executed command and cleaned response
print(f"Executed command: {executed_commands[-1]}")
print(f"Cleaned Response: {response_text.strip()}")

i added re.sub function to remove the echoed command from the response text, taking into account any control characters that might be present. I hope this helps

Upvotes: 0

Related Questions