#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    5
    Rep Power
    0

    Python Pexpect SSH Command Line Login Arguments


    I'm using the pexpect.py script to login and get hostname information.
    Basically I run it like this:
    Code:
    ~$:./pexpect.py -h{hostname} -u{user} -p{password}
    You will see below that it's automated to run a few commands and close out. I'd like to be able to add line at the end so the user can pick and choose what information they would like to see. So instead of the above command line it would look something like:
    Code:
    ~$:./pexpexct.py -h{hostname} -u{username} -p{password} -x{user defined} -z{user defined}
    **nothing would be after the -x -z......**

    Basically a list with -x being.. say uptime and -z being ifconfig.. there would also be -a, -b , -c. I'm lost as how to add those arguments in the code:

    Code:
     #!/usr/bin/env python
    # -h : hostname of the remote server to login to.
    # -u : username to user for login.
    # -p : Password to user for login. 
    
    import os, sys, time, re, getopt, getpass
    import traceback
    import pexpect
    
    COMMAND_PROMPT = '[#$] '
    TERMINAL_PROMPT = '(?i)terminal type\?'
    TERMINAL_TYPE = 'vt100'
    
    SSH_NEWKEY = '(?i)are you sure you want to continue connecting'
    
    def exit_with_usage():
        print globals()['__doc__']
        os._exit(1)
    
    def main():
        global COMMAND_PROMPT, TERMINAL_PROMPT, TERMINAL_TYPE, SSH_NEWKEY
        ## Parse the options, arguments, get ready, etc.
        try:
            optlist, args = getopt.getopt(sys.argv[1:], 'h:u:p:', ['help','?'])
        except Exception, e:
            print str(e)
            exit_with_usage()
        options = dict(optlist)
        if len(args) > 1:
            exit_with_usage()
    
        if [elem for elem in options if elem in ['-?','--?','--help']]:
            print "Help:"
            exit_with_usage()
    
        if '-h' in options:
            host = options['-h']
        else:
            host = raw_input('hostname: ')
        if '-u' in options:
            user = options['-u']
        else:
            user = raw_input('username: ')
        if '-p' in options:
            password = options['-p']
        else:
            password = getpass.getpass('password: ')
    
    ## Login via SSH
    
        child = pexpect.spawn('ssh -l %s %s'%(user, host))
        i = child.expect([pexpect.TIMEOUT, SSH_NEWKEY, COMMAND_PROMPT, '(?i)password'])
        if i == 0:
                print 'ERROR! could not login with SSH. Here is what SSH said:'
                print child.before, child.after
                print str(child)
                sys.exit (1)
        if i == 1: # In this case SSH does not have the public key cached.
                child.sendline ('yes')
                child.expect ('(?i)password')
        if i == 2:
                # This may happen if a public key was setup to automatically login.
                # But beware, the COMMAND_PROMPT at this point is very trivial and
                # could be fooled by some output in the MOTD or login message.
                pass
        if i == 3:
                child.sendline(password)
                # Now we are either at the command prompt or
                # the login process is asking for our terminal type.
                i = child.expect ([COMMAND_PROMPT, TERMINAL_PROMPT])
                if i == 1:
                    child.sendline (TERMINAL_TYPE)
                    child.expect (COMMAND_PROMPT)
    
            COMMAND_PROMPT = "\[PEXPECT\]\$ "
            child.sendline ("PS1='[PEXPECT]\$ '") # In case of sh-style
            i = child.expect ([pexpect.TIMEOUT, COMMAND_PROMPT], timeout=10)
            if i == 0:
                print "# Couldn't set sh-style prompt -- trying csh-style."
                child.sendline ("set prompt='[PEXPECT]\$ '")
                i = child.expect ([pexpect.TIMEOUT, COMMAND_PROMPT], timeout=10)
                if i == 0:
                    print "Failed to set command prompt using sh or csh style."
                    print "Response was:"
                    print child.before
                    sys.exit (1)
    
    # Now we should be at the command prompt and ready to run some commands.
    # print '---------------------------------------'
    # print 'Report of commands run on remote host.'
    # print '---------------------------------------'
    
    # Run uname.
            child.sendline ('uname -a')
            child.expect (COMMAND_PROMPT)
            print child.before
            if 'linux' in child.before.lower():
                LINUX_MODE = 1
            else:
                LINUX_MODE = 0
    
    # Run and parse 'uptime'.
            child.sendline ('uptime')
            child.expect('up\s+(.*?),\s+([0-9]+) users?,\s+load averages?: ([0-9]+\.[0-9][0-9]),?\s+([0-9]+\.[0-9][0-9]),?\s+([0-9]+\.[0-9][0-9])')
        duration, users, av1, av5, av15 = child.match.groups()
            days = '0'
            hours = '0'
            mins = '0'
            if 'day' in duration:
                child.match = re.search('([0-9]+)\s+day',duration)
                days = str(int(child.match.group(1)))
            if ':' in duration:
                child.match = re.search('([0-9]+):([0-9]+)',duration)
                hours = str(int(child.match.group(1)))
                mins = str(int(child.match.group(2)))
            if 'min' in duration:
                child.match = re.search('([0-9]+)\s+min',duration)
                mins = str(int(child.match.group(1)))
            print
            print 'Uptime: %s days, %s users, %s (1 min), %s (5 min), %s (15 min)' % (
                duration, users, av1, av5, av15)
            child.expect (COMMAND_PROMPT)
    
    # Run Current Date.
            child.sendline ('date')
            child.expect (COMMAND_PROMPT)
            print child.before
    
    # Run vmstat.
        #    child.sendline ('vmstat')
        #    child.expect (COMMAND_PROMPT)
        #    print child.before
    
    # Run free.
        #    if LINUX_MODE:
        #        child.sendline ('free') # Linux systems only.
        #        child.expect (COMMAND_PROMPT)
        #        print child.before
    
    # Run df.
        #    child.sendline ('df')
        #    child.expect (COMMAND_PROMPT)
        #    print child.before
    
    # Run lsof.
        #    child.sendline ('lsof')
        #    child.expect (COMMAND_PROMPT)
        #    print child.before
    
    # Run netstat
        #    child.sendline ('netstat')
        #    child.expect (COMMAND_PROMPT)
        #    print child.before
    
    # Run MySQL show status.
        #    child.sendline ('mysql -p -e "SHOW STATUS;"')
        #    child.expect (PASSWORD_PROMPT_MYSQL)
        #    child.sendline (password_mysql)
        #    child.expect (COMMAND_PROMPT)
        #    print
        #    print child.before
    
    # Now exit the remote host.
            child.sendline ('exit')
            index = child.expect([pexpect.EOF, "(?i)there are stopped jobs"])
            if index==1:
                child.sendline("exit")
                child.expect(EOF)
    
        if __name__ == "__main__":
    
            try:
                main()
            except Exception, e:
                print str(e)
                traceback.print_exc()
                os._exit(1)
  2. #2
  3. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,841
    Rep Power
    480
    Someone else wrote pexpect.py?
    http://pexpect.sourceforge.net/pexpect.html

    You're not a computer programmer?

    Programming is old hat to you but python is new?
    [code]Code tags[/code] are essential for python code and Makefiles!
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    5
    Rep Power
    0
    Correct. I did not write the above. Never claimed I did.

    I'm trying to tailor it towards my use since it's something that works well.

    $: ssh user@host 'ifconfig; etc' works well. Looking to do similar but with the above script.
  6. #4
  7. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,841
    Rep Power
    480
    I try to learn what kind of answer you need. What are your computer programming skills? How should we answer in a helpful way?

    getopt.getopt returns a tuple containing 2 objects. A python tuple is an immutable list. The second of these contains the command line arguments that remain after removing those that getopt recognizes.

    I think you want to have this script evaluate additional commands on the remote server. There's no need for -x -y -z -a or -b. The new command line looks like this
    Code:
    ./pexpexct.py -h{hostname} -u{username} -p{password}  'first_command -with args'  'second_command'
    If you're a python programmer, the following should be sufficient:

    You'd need to remove
    Code:
    if len(args) > 1:
            exit_with_usage()
    from the script you posted, and then you'd insert code like
    Code:
        for arg in args:
            child.sendline (arg)
            child.expect (COMMAND_PROMPT)
            print child.before
    and you'd place this code right after
    Code:
    # Run Current Date.
            child.sendline ('date')
            child.expect (COMMAND_PROMPT)
            print child.before
    If you're not a python programmer and I've messed up the indentation level or have another of the myriad problems I run into with untested code then you'll need more help.
    Last edited by b49P23TIvg; November 5th, 2012 at 01:52 PM.
    [code]Code tags[/code] are essential for python code and Makefiles!
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    5
    Rep Power
    0
    Originally Posted by b49P23TIvg
    I try to learn what kind of answer you need. What are your computer programming skills? How should we answer in a helpful way?

    If you're not a python programmer and I've messed up the indentation level or have another of the myriad problems I run into with untested code then you'll need more help.
    First, I'd like to say thank you for taking the time to help me.
    I'm not really a programmer, I'm slowly learning.

    I'm not currently at the office, but I will throw those in tomorrow morning and let you know how it went. Thank you.
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    5
    Rep Power
    0
    Worked perfectly.

    Thank you for the help.

IMN logo majestic logo threadwatch logo seochat tools logo