Search code examples
pythonsshparamiko

Python Paramiko doesn't show commands output in the right order


When I run the following code, I get a distorted result:

######## Make connection

remote_conn_pre=paramiko.SSHClient()
remote_conn_pre.set_missing_host_key_policy(paramiko.AutoAddPolicy())
remote_conn_pre.connect(ip, port=22, username=username,
                        password=password,
                        look_for_keys=False, allow_agent=False)

remote_conn = remote_conn_pre.invoke_shell()

######## commands read from JSON file (commands)

for command in commands["normal"]:
    print("-- command: " + command)
    remote_conn.send(command + "\n")
    while not remote_conn.recv_ready():
        time.sleep(0.300)
    output = remote_conn.recv(buffersize)
    print(output.decode())

Output result:

-- command: sh run | section dhcp
sh run | sec dhcp

-- command: sh run | i ip route
ip dhcp bootp ignore 
sh run | i ip route
ip route 0.0.0.0 0.0.0 vlan 1

As you can see the ip dhcp bootp ignoreresult should be under the "DHCP section" and not onder the "route section".

The correct result should be:

-- command: sh run | section dhcp
sh run | sec dhcp
ip dhcp bootp ignore 

-- command: sh run | i ip route
sh run | i ip route
ip route 0.0.0.0 0.0.0 vlan 1

What is going wrong here? I thought about the command not being ready so I've built in the sleep timer. Yet it seems the buffer isn't empty or ready after this.


Solution

  • Because you do not wait for the command to finish before sending another. And there's actually no way to do that with SSHClient.invoke_shell (SSH "shell" channel). The "shell" channel is not intended for command automation.

    Instead, use SSHClient.exec_command (SSH "exec" channel).
    See Wait until task is completed on Remote Machine through Python


    If some of your commands are actually not top-level shell commands, but subcommands of the top-level commands, see also:
    Execute (sub)commands in secondary shell/command on SSH server in Python Paramiko