7

I am trying to telnet to Cisco Router and give commands using pexpect. Its working, but the sendline() repeats in the output. even after using setecho to False. Code is:

'''
Created on Nov 19, 2012

@author: Amit Barik
'''

import pexpect

hostname = 'hostname'
login_cmd = 'telnet ' + hostname + '.net'
username = 'username'
password = 'pwd'
prompt = hostname + '#'

p = pexpect.spawn(login_cmd)
p.setecho(False)
p.logfile = open('Log.log', 'w+')

p.expect('Username:')
print '1',repr(p.before)

p.sendline(username)
p.expect('Password:')
print '2',repr(p.before)

p.sendline(password)
p.expect(prompt)
print '3',repr(p.before)

cmd = 'show clock'
p.sendline(cmd)
p.expect(prompt)
print 'Output for {0}'.format(cmd), repr(p.before)

Output is:

# On Python Console
Output for show clock 'show clock\r\n00:16:40.692 UTC Tue Nov 20 2012\r\n'

# On Log File
Username: username
username
Password: pwd

My Cisco Banner

hostname#show clock
show clock
00:16:40.692 UTC Tue Nov 20 2012
hostname#
amulllb
  • 3,036
  • 7
  • 50
  • 87

3 Answers3

12

I had the same problem when interacting with network devices (not *nix terminals).

Pexpect has 3 logging methods (1. logfile_send(), 2. logfile_read() 3. logfile()).

Using the output example from the original poster above, here is what the output looks like for each logging method:

1.) p.logfile() will log the network device's echo'd output AND it will log the text sent using send() & sendline(). This is what the original poster did NOT want to happen.

In script:

p.logfile = open('Log.log', 'w+')

Output:

# On Python Console
Output for show clock 'show clock\r\n00:16:40.692 UTC Tue Nov 20 2012\r\n'

# On Log File
Username: username   #This is the `sendline()` output
username             #This is echo from the network device
Password: pwd        #This is `sendline()` output
                     #Notice, pwd only echo's once.  There is no echo from the network device since it doesn't echo passwords

My Cisco Banner

hostname#show clock  #This is the `sendline()` output
show clock           #This is echo from the network device
00:16:40.692 UTC Tue Nov 20 2012
hostname#

2.) p.logfile_read() will ONLY log the network device's echo'd output. It will not log p.sendline() characters. This is the desired result the original poster was looking for.

In script:

p.logfile_read = open('Log.log', 'w+')

Output:

# On Python Console
Output for show clock 'show clock\r\n00:16:40.692 UTC Tue Nov 20 2012\r\n'

# On Log File
Username: username   #This is echo from the network device
Password:            #There is no echo from the network device since it doesn't echo passwords

My Cisco Banner

hostname#show clock  #This is echo from the network device
00:16:40.692 UTC Tue Nov 20 2012
hostname#

3.) p.logfile_sendwill only send the p.sendline() characters to the log, which probably isn't very useful in most cases. I'll skip the example, since everyone probably has the idea by now.

So, using logfile_read() will fix the issue with passwords showing in the log output when interacting with network devices. This will also fix the issue of pexpect showing double echo's in log output, which I've seen a few people ask questions about online as well.

Regarding setecho(False), per the pexpect docs, this sets the "terminal echo mode on or off". That function isn't meant to surpress sendline() output as people were hoping (including myself). And since I was dealing with a network device (cisco, juniper, mrv, etc), trying to turn off tty echo wasn't useful.

Hope this helps someone out in the future.

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
ne_denver
  • 121
  • 1
  • 3
  • 1
    It seems like you understand. Can you provide an example? Do you explicitly call `logfile_read()`? Or do you just set the function to something and `pexpect` will call the method on it's own? – Johnston Dec 14 '14 at 17:26
0

So, what I have found is...

  • setecho just doesn't seem to work (in the pexpect.before output, the pexpect.sendline text is present). Only solution is to do string stripping. Something like pseudo code pexpect.before.strip(pexpect.sendline)
  • Also, while logging, logfile_read doesn't contain the echoes, but logfile contains (irrespective of setecho value)
mercator
  • 28,290
  • 8
  • 63
  • 72
amulllb
  • 3,036
  • 7
  • 50
  • 87
0

I used to have the same problem with echos, even when echo was turned off.

But I might have found a solution:

commandToRun = 'bash -c "less /readfile | tail -4"'
yourConnection.sendLine("stty -echo")
commandResult = yourConnection.sendLine(commandToRun)
self.sendLine("stty echo")

So basically, run you command in a shell using 'bash -c' and then turn of echo in the bash.

theAlse
  • 5,577
  • 11
  • 68
  • 110