Select Page

Reading the SSH Output – about 20 minutes

Our next step is conceptually pretty straightforward, but the details are a bit complicated. We’re using Paramiko to pretend programmatically like we are a human being using an SSH connection. We send commands to the host. The host executes the command and then sends back the results. That concept is sensible. The real world introduces complications for us though. The real world introduces things like latency due to packets flying all over the internet. So we need to handle the real world.

Our solution for handling the real world is to improve how we are reading data back from the host. Our current effort to retrieve the data is:

For the purpose of testing this is a decent solution. We’re calling the Paramiko channel‘s recv(). That function reads whatever data the device has already sent back to our program. That does not account for the latency of the real world.

So we now introduce our new function:

Note that this is a new function we’re calling. The function combines sending the command to the device plus making sure we read back from the device, even if there is latency.

Our new function starts out by making sure that we always add a “line feed” (think of the enter key) to the end of our command. Then is delegates its real work to the get_command_results() function. Now, that’s where things get a little more complicated.

You can wade into some deeper water with me here or just skip to the next section. We’re going to look at the techniques we’re using to read the response from the device.

Deep Dive

get_command_results() is, at its heart, an infinite loop that starts with while True:. Each time the program goes through the loop it is going to evaluate the statements in order.

  1. Check whether there is anything to be read back from the device (channel.recv_ready()). Read back the data if there is anything.
  2. If the channel doesn’t have any further data then exit_status_ready() returns True. In that case we’ll hit the break command. The break will cause our while loop to end.
  3. Next we check whether we’ve been waiting for too long. If our function has been trying for longer than maxseconds then we’ll break out of the loop. We need to be patient enough to wait for the response, but we can’t just wait forever. So we make a judgement call on what the maxseconds should be.
  4. So we check next whether we have received from the device a Cisco command prompt. That would indicate that the device is finished responding to this command. We’re looking at the output and copying it to rbuffer. If our results ends with either a hash sign (#) or a greater than sign (>) then we break out of the while loop. We’re assuming that either of those characters at the end of the results indicates a command prompt.
  5. Then we take a little rest before looping around and checking whether there’s any more info.

After the loop we take one last look with recv_ready() to see if we can get any further data. And then we return everything we’ve received.

Share This