2

I have an issue that has been giving me a headache for a few days. I am using the Paramiko module with Python 2.7.10 and I'd like to issue multiple commands to a Brocade router, but only return output from one of the given commands like so:

#!/usr/bin/env python import paramiko, time router = 'r1.test.example.com' password = 'password' username = 'testuser' ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(router, username=username, password=password) print('Successfully connected to %s' % router) remote_conn = ssh.invoke_shell() output = remote_conn.recv(1000) # Disable paging on Brocade. remote_conn.send('terminal length 0\n') # Check interface status. remote_conn.send('show interfaces ethernet 0/1\n') # I only want output from this command. time.sleep(2) output = remote_conn.recv(5000) print(output) 

If I were to print the full output it would contain everything issued to the router, but I only want to see output from the show interfaces ethernet 0/1\n command.

Can anyone help with this issue?

One final thing I would like to ask. I want to filter through the output variable and check for occurrences of strings like "up" or "down", but I can't seem to get it to work because everything in the output appears to be on new lines?

For example:

If I iterate over the output variable in a for loop I get all of the characters in the variable like so:

for line in output: print(line) 

I get an output like this:

t

e

r

m

i

n

a

l

l

e

n

g

t

h

0

Any way around this?

Again,

Thanks in advance for any help.

Best regards,

Aaron C.

1
  • Arguably, this could (should) be narrowed -- the problem at hand isn't particular to paramiko at all; you could run output='terminal length 0', followed by for line in output: print(line) and have the same question with much less boilerplate. Commented Oct 17, 2016 at 21:02

3 Answers 3

6

After reading all of the comment I have made the following changes:

#!/usr/bin/env python import paramiko, time router = 'r2.test.example.com' password = 'password' username = 'testuser' ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect(router, username=username, password=password) print('Successfully connected to %s' % router) remote_conn = ssh.invoke_shell() output = remote_conn.recv(1000) # Disable paging on Brocade. remote_conn.send('terminal length 0\n') time.sleep(2) # Clearing output. if remote_conn.recv_ready(): output = remote_conn.recv(1000) # Check interface status. remote_conn.send('show interfaces ethernet 4/1\n') # I only want output from this command. time.sleep(2) # Getting output I want. if remote_conn.recv_ready(): output = remote_conn.recv(5000) print(output) # Test: Check if interface is up. for line in output.split('\n'): if 'line protocol is up' in line: print(line) 

Everything works great now.

Thank you for all the help.

Best regards,

Aaron C.

Sign up to request clarification or add additional context in comments.

2 Comments

Nice, I'm surprised this post has so little +1's. Really useful.
This post is abundantly helpful. I was creating only the client, but not the shell invocation. It saves me plenty of headaches.
2

For your second question: Though I am not specialist of paramiko, I see that function recv, according to the doc, returns a string. If you apply a for loop on a string, you will get characters (and not lines as one might perhaps expect). The newline is caused by your use of the print function as explained on this page, at paragraph 6.3.

I haven't studied what paramiko suggests to do. But why don't you treat the full string as a single entity? For example, you could check the presence of "up" as:

if "up" in output: 

Or, if that suits your needs better, you could split the string into lines and then do whatever test you want to do:

for line in output.split('\n'): 

1 Comment

Works perfectly. Now it will be a lot easier for me to filter through the variable. Thank you very much for the quick answer!
0

If you can, the exec_command() call provides a simpler mechanism to invoke a command. I have seen Cisco switches abruptly drop connections that try exec_command(), so that may not be usable with Brocade devices.

If you must go the invoke_shell() route, be sure to clear all pending output after connecting and after send('terminal length 0\n'), checking recv_ready() before calling recv() to avoid blocking on reading data that might not ever arrive. Since you are controlling an interactive shell, sleep() calls might be needed to allow the server adequate time to process and send data, or it might be necessary to poll the output string to confirm that your last command completed by recognizing the shell prompt string.

1 Comment

I added an if statement to check if recv_ready(), and it works. Now I can get output from the commands that I actually want! Thanks.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.