Monday, May 14, 2012

Python pexpect - TIMEOUT falls into traceback and exists,

I'm new to python-pexpect. In Tcl/expect when I hit a timeout - I would respond with message and exit the function. I have tried to experiment with similar response using sample code posted
http://pexpect.svn.sourceforge.net/viewvc/pexpect/trunk/pexpect/examples/sshls.py?revision=489&view=markup



I based on this code above - if I give a bogus password, I would expect this to just timeout, print "ERROR!", and exit program. But when I run it - goes into a 'Traceback output (see below), can someone help me to get the program to print "ERROR" and exit program gracefully.



test@ubuntu:~/scripts$ ./tmout.py 
Hostname: 192.168.26.84
User: root
Password:
Timeout exceeded in read_nonblocking().
<pexpect.spawn object at 0xb77309cc>
version: 2.3 ($Revision: 399 $)
command: /usr/bin/ssh
args: ['/usr/bin/ssh', '-l', 'root', '192.168.26.84', '/bin/ls', '-l']
searcher: searcher_re:
0: EOF
buffer (last 100 chars):
Permission denied, please try again.
root@192.168.26.84's password:
before (last 100 chars):
Permission denied, please try again.
root@192.168.26.84's password:
after: <class 'pexpect.TIMEOUT'>
match: None
match_index: None
exitstatus: None
flag_eof: False
pid: 14997
child_fd: 3
closed: False
timeout: 30
delimiter: <class 'pexpect.EOF'>
logfile: None
logfile_read: None
logfile_send: None
maxread: 2000
ignorecase: False
searchwindowsize: None
delaybeforesend: 0.05
delayafterclose: 0.1
delayafterterminate: 0.1
Traceback (most recent call last):
File "./tmout.py", line 54, in <module>
traceback.print_exc()
NameError: name 'traceback' is not defined
test@ubuntu:~/scripts$


Source Code:



#!/usr/bin/env python

"""This runs 'ls -l' on a remote host using SSH. At the prompts enter hostname,
user, and password.

$Id$
"""

import pexpect
import getpass, os

def ssh_command (user, host, password, command):

"""This runs a command on the remote host. This could also be done with the
pxssh class, but this demonstrates what that class does at a simpler level.
This returns a pexpect.spawn object. This handles the case when you try to
connect to a new host and ssh asks you if you want to accept the public key
fingerprint and continue connecting. """

ssh_newkey = 'Are you sure you want to continue connecting'
child = pexpect.spawn('ssh -l %s %s %s'%(user, host, command))
i = child.expect([pexpect.TIMEOUT, ssh_newkey, 'password: '])
if i == 0: # Timeout
print 'ERROR!'
print 'SSH could not login. Here is what SSH said:'
print child.before, child.after
return None
if i == 1: # SSH does not have the public key. Just accept it.
child.sendline ('yes')
child.expect ('password: ')
i = child.expect([pexpect.TIMEOUT, 'password: '])
if i == 0: # Timeout
print 'ERROR!'
print 'SSH could not login. Here is what SSH said:'
print child.before, child.after
return None
child.sendline(password)
return child

def main ():

host = raw_input('Hostname: ')
user = raw_input('User: ')
password = getpass.getpass('Password: ')
child = ssh_command (user, host, password, '/bin/ls -l')
child.expect(pexpect.EOF)
print child.before

if __name__ == '__main__':
try:
main()
except Exception, e:
print str(e)
traceback.print_exc()
os._exit(1)




No comments:

Post a Comment