0

I am trying to run multiple commands using paramiko. Channel.recv raises paramiko.buffered_pipe.PipeTimeout exactly after reading 9999 lines from server.

I am connecting to remote Windows server 2012 with openssh installed from linux. Output from windows server has ANSI sequences and H code, so I could see Channel.recv waits for timeout after reading 9999 lines. Channel.recv(buffer_size) waits for timeout after this output b'\x1b[9999;54H'(9999 line, 54 column).

Here is my minimal reproducible example:

client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hostname=hostname, username=username, password=password)

interact = SSHClientInteraction(client, timeout=60, display=True, buffer_size=65535, tty_width=100, tty_height=24)
interact.expect(r".*C:\\Users\\Administrator>.*", strip_ansi=False)

interact.send('dir')
interact.expect(r".*C:\\Users\\Administrator>.*", strip_ansi=False)
cmd_output_dir = interact.current_output_clean

for i in range(100):
    interact.send('ipconfig')
    interact.expect(r".*C:\\Users\\Administrator>.*", strip_ansi=False)
    cmd_output_dir = interact.current_output_clean

    interact.send('ipconfig')
    interact.expect(r".*C:\\Users\\Administrator>.*", strip_ansi=False)
    cmd_output_dir = interact.current_output_clean

    interact.send('dir')
    interact.expect(r".*C:\\Users\\Administrator>.*", strip_ansi=False)
    cmd_output_dir = interact.current_output_clean

    interact.send('dir')
    interact.expect(r".*C:\\Users\\Administrator>.*", strip_ansi=False)
    cmd_output_dir = interact.current_output_clean

    interact.send('ipconfig')
    interact.expect(r".*C:\\Users\\Administrator>.*", strip_ansi=False)
    cmd_output_dir = interact.current_output_clean

    interact.send('ipconfig')
    interact.expect(r".*C:\\Users\\Administrator>.*", strip_ansi=False)
    cmd_output_dir = interact.current_output_clean

I see paramiko_expect reads available data until prompt matches in the received output with Channel.recv. So, problem may not be with reading large output. Could it be a problem with data availability from the server? Can anyone help me to resolve this please?

EDIT I have tried to reproduce this problem WITHOUT using paramiko_expect. I still could see same issue. Before getting PipeTimeout, I see incomplete output from the command. Here is the code:

re_strings = [r".*C:\\Users\\Administrator>.*", ".*Command:.*"]
default_match_prefix = ".*\n"

# Use SSH client to login
# Create a new SSH client object
client = paramiko.SSHClient()

# Set SSH key parameters to auto accept unknown hosts
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

# Connect to the host
client.connect(hostname=hostname, username=username, password=password)
client.get_transport().window_size = 3 * 1024 * 1024 * 1024
channel = client.invoke_shell(width=100, height=24)
channel.settimeout(10800)
channel.set_combine_stderr(True)

for i in range(100):
    for cmd in ['ipconfig', 'ipconfig', 'dir', 'dir', 'ipconfig', 'ipconfig', 'ipconfig']:
        # import time
        # time.sleep(1)
        channel.send(cmd + "\r")

        # Create an empty output buffer
        current_output = ''

        # Loop until one of the expressions is matched or loop forever if
        # nothing is expected (usually used for exit)
        while (not [re_string for re_string in re_strings
                    if re.match(default_match_prefix + re_string + '$', current_output, re.DOTALL)]):

            # # Read some of the output
            current_output += channel.recv(len(channel.in_buffer)).decode('utf-8')

            # If we have an empty buffer, then the SSH session has been closed
            if len(current_output) == 0:
                break
Suresh Kota
  • 305
  • 1
  • 6
  • 19

0 Answers0