Welcome, guest | Sign In | My Account | Store | Cart

Send commands to one or more logins using Python's standard telnetlib module.

Python, 79 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# auto_telnet.py - remote control via telnet
import os, sys, string, telnetlib
from getpass import getpass

class AutoTelnet:
    def __init__(self, user_list, cmd_list, **kw):
        self.host = kw.get('host', 'localhost')
        self.timeout = kw.get('timeout', 600)
        self.command_prompt = kw.get('command_prompt', "$ ")
        self.passwd = {}
        for user in user_list:
            self.passwd[user] = getpass("Enter user '%s' password: " % user)
        self.telnet = telnetlib.Telnet()
        for user in user_list:
            self.telnet.open(self.host)
            ok = self.action(user, cmd_list)
            if not ok:
                print "Unable to process:", user
            self.telnet.close()

    def action(self, user, cmd_list):
        t = self.telnet
        t.write("\n")
        login_prompt = "login: "
        response = t.read_until(login_prompt, 5)
        if string.count(response, login_prompt):
            print response
        else:
            return 0
        password_prompt = "Password:"
        t.write("%s\n" % user)
        response = t.read_until(password_prompt, 3)
        if string.count(response, password_prompt):
            print response
        else:
            return 0
        t.write("%s\n" % self.passwd[user])
        response = t.read_until(self.command_prompt, 5)
        if not string.count(response, self.command_prompt):
            return 0
        for cmd in cmd_list:
            t.write("%s\n" % cmd)
            response = t.read_until(self.command_prompt, self.timeout)
            if not string.count(response, self.command_prompt):
                return 0
            print response
        return 1

if __name__ == '__main__':
    basename = os.path.splitext(os.path.basename(sys.argv[0]))[0]
    logname = os.environ.get("LOGNAME", os.environ.get("USERNAME"))
    host = 'localhost'
    import getopt
    optlist, user_list = getopt.getopt(sys.argv[1:], 'c:f:h:')
    usage = """
usage: %s [-h host] [-f cmdfile] [-c "command"] user1 user2 ...
    -c  command
    -f  command file
    -h  host  (default: '%s')

Example:  %s -c "echo $HOME" %s
""" % (basename, host, basename, logname)
    if len(sys.argv) < 2:
        print usage
        sys.exit(1)
    cmd_list = []
    for (opt, optarg) in optlist:
        if opt == '-f':
            for r in open(optarg).readlines():
                if string.rstrip(r):
                    cmd_list.append(r)
        elif opt == '-c':
            command = optarg
            if command[0] == '"' and command[-1] == '"':
                command = command[1:-1]
            cmd_list.append(command)
        elif opt == '-h':
            host = optarg
    autoTelnet = AutoTelnet(user_list, cmd_list, host=host)

Python's telnetlib permits users to easily automate access to telnet servers, even from non-Unix machines.

As an alternative to the popen() functions, telnetlib is probably a handy technique to have in your sysadmin toolbox.

Production code will generally be more robust, but this example should be enough to get anyone started in the right direction.

3 comments

Dave Warner 20 years, 9 months ago  # | flag

Note use of dict.get(key, defaultval). Nice demonstration of dict.get(key, defaultval) - I seem to spend half my days in other languages coding this type of sequence in a much less concise manner. Dave Warner

Noah Spurrier 19 years, 2 months ago  # | flag

Try Pexpect and do the same with SSH. Pexpect is perfect for this type of application. Using Pexpect you can do the same thing with SSH.

Find Pexpect here:

http://pexpect.sourceforge.net/

stewart midwinter 16 years, 10 months ago  # | flag

sorry, nix only. Pexpect only works on *nix systems, so don't waste your time looking at it if you use Win.