I try to make a telnet connection using subprocess, threading and pexpect modules to subscript, but I constantly fail even though manual telnet connection is available. Could you help me spot the problem? The commands should be issued in this order too "microcom /dev/ttyS3" in main script > telnet connection to subscript > "root" in subscript > "microcom /dev/ttyS6" in subscript > "Response from subscript" in subscript > "Response from main script" in main script. Bear in mind, the process of "microcom /dev/ttyS3" from main script and should remain and the whole process of subscript should be executed until the "Response from main script" is executed
Main Script:
import time
import sys
import re
import subprocess
import threading
import pexpect
# Replace with your actual COM port (e.g., COM1, COM2, etc.)
COM_Num = input("Type in COM port number: ")
COM_PORT = "COM" + COM_Num # Adjust based on your system
BAUD_RATE = 115200 # Adjust based on your device
# Open the serial connection
ser = serial.Serial(COM_PORT, baudrate=BAUD_RATE, timeout=2)
# Send 'root' command and press Enter to loginprint("Sending 'root' to login...") send_command("root")
# Send the 'root' commandprint("Sent 'root', now waiting for Enter...") send_command("")
# Send Enter (empty command simulates pressing Enter)
print(f"Successfully connected to {COM_PORT} at {BAUD_RATE} baud rate.")
# Function to send command and receive response
def send_command(command):
print(f"Sending command: {command}")
ser.write((command + '\n').encode()) # Send command (make sure to encode as bytes)
time.sleep(1) # Give the device time to process
response = ser.readlines() # Read the response (might need to adjust this depending on the device)
response = [line.decode('utf-8').strip() for line in response] # Decode bytes to string
return response
def extract_ip(response):
ip_pattern = r"\d+\.\d+\.\d+\.\d+" # Regular expression to match an IP address
for line in response:
match = re.search(ip_pattern, line)
if match:
return match.group(0)
return None
# Send command to get the IP address
response = send_command("") # This can be the empty command or a specific one to get the IP
print("Response from device:", response)
# Extract the IP address
device_ip = extract_ip(response)
if device_ip:
print(f"Device IP address extracted: {device_ip}")
else:
print("No IP address found in the response.")
sys.exit(1) # Exit if no IP address is found
# Root command to be sent
root_command = 'root'
response = send_command(root_command)
response = send_command("microcom /dev/ttyS3")
def run_telnet_commands():
max_retries = 3
retry_delay = 2 # seconds
for attempt in range(max_retries):
try:
print(f"Attempting to establish Telnet connection (attempt {attempt + 1}/{max_retries})...")
# First verify device is reachable
ping_result = subprocess.run(['ping', '-n', '1', device_ip], capture_output=True, text=True)
if "Reply from" not in ping_result.stdout:
print(f"Device {device_ip} is not responding to ping. Waiting {retry_delay} seconds...")
time.sleep(retry_delay)
continue
# Start telnet3.py using pexpect, passing the IP address to it
print(f"Starting telnet3.py to connect to {device_ip}...")
telnet_script = pexpect.spawn(f"python telnet3.py {device_ip}", timeout=30)
telnet_script.logfile = sys.stdout # Optional: Log all output for debugging
# Expect the end of telnet3.py and capture the output
telnet_script.expect("Telnet script finished.")
telnet_script.close()
break # Exit after successful connection and command execution
except Exception as e:
print(f"Error establishing Telnet connection: {e}")
if attempt < max_retries - 1:
print(f"Retrying in {retry_delay} seconds...")
time.sleep(retry_delay)
else:
print("Failed to establish Telnet connection after maximum retries.")
return
else:
print("Failed to establish Telnet connection after maximum retries.")
return
# Run the Telnet commands
if __name__ == "__main__":
run_telnet_commands()
sys.stdout.write('Press Enter to exit.')
sys.stdin.readline()
sys.exit(0)
subscript:
import time
import sys
# Device connection parameters (this will now take the IP as a command-line argument)
if len(sys.argv) < 2:
print("Error: No IP address provided!")
sys.exit(1)
HOST = sys.argv[1] # Get the IP address passed from the base script
PORT = 24 # Telnet default port (can use 23 if that’s what the device uses)
TIMEOUT = 2 # Timeout for expect commands
# Login credentials
USERNAME = "root" # Assuming the username is "root"
COMMAND_2 = "microcom /dev/ttyS6" # Command 2 to send after logging in
response = "response from terminal two" # The response to send after command execution
def telnet_connect():
try:
# Establish Telnet connection with pexpect
print(f"Connecting to {HOST}:{PORT}...")
tn = pexpect.spawn(f"telnet {HOST} {PORT}", timeout=TIMEOUT)
# Expect login prompt and send the username
tn.expect("login: ")
tn.sendline(USERNAME)
# Give the system some time to respond
tn.expect("# ") # Expect the prompt after login (adjust if necessary)
# Execute the second command (microcom)
tn.sendline(COMMAND_2)
tn.expect("# ") # Wait for prompt after executing command
# Send response back from terminal 2
tn.sendline(response)
tn.expect("# ") # Wait for prompt after executing command
# Capture and return the output
output = tn.before.decode('ascii') # Grab everything before the last prompt
print("Command executed successfully. Output captured:")
print(output)
# Close the Telnet session
tn.sendline("exit") # Send 'exit' to close the session
tn.close()
return output
except Exception as e:
print(f"Error during Telnet connection: {e}")
sys.exit(1) # Exit the script if there's an error
# Connect to the device and run the commands
if __name__ == "__main__":
result = telnet_connect()
print("Telnet script finished.")```