Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Using telnetlib.py

2,426 views
Skip to first unread message

Philippe Tempel

unread,
Jan 4, 1999, 3:00:00 AM1/4/99
to
I'm currently learning Python and want to write a small script
that uses the telnetlib module to automate logging into a Unix
box. Here's the script so far:

# Test script for the Python telnetlib.
#
# This script will test the Python telnetlib interface by running
# a simple unix command on the remote machine and printing the
# results.
#

from telnetlib import Telnet

max_wait = 30 # set the timeout value
prompt = ']$' # set the prompt string
user_login = 'joeblow\r\n' # the username to login with
user_passwd = 'letMEin\r\n' # the password for the user

tn = Telnet('10.1.1.4') # connect using port 23 (default)
tn.read_until("login:", max_wait)
tn.write(user_login)
tn.read_until("Password:", max_wait)
tn.write(user_passwd)
tn.read_until("prompt", max_wait)
tn.write('df\r\n');
print tn.read_all()
tn.close()

Has anyone used this module yet? The program runs but seems to
hang in limbo for a while. Any pointers to docs and/or code
snippets would be welcome. I have already read the telnetlib.py
module itself and also ran the example test() function it
provides. It's just not very explanatory and doesn't do very
much.

Thankx,
Philippe

Jeffrey C. Ollie

unread,
Jan 5, 1999, 3:00:00 AM1/5/99
to
In article <36915AF9...@erols.com>, Philippe Tempel
<tem...@erols.com> wrote:
> [...]

> tn.write(user_passwd)
> tn.read_until("prompt", max_wait)
^^^^^^^^

> tn.write('df\r\n');
> print tn.read_all()
> tn.close()
>
> Has anyone used this module yet? The program runs but seems to
> hang in limbo for a while.

Try removing the quotes from around the reference to the variable
prompt.

--
Jeff

Janko Hauser

unread,
Jan 5, 1999, 3:00:00 AM1/5/99
to
I have tried to run the code and see at first glance no error, besides
the linedelimiter. I think '\012' ('\n') are enough. If I change your
last lines from

tn.write('df\r\n');
print tn.read_all()

to

tn.write('df\n');
print tn.read_until("prompt", max_wait)

everything functions fine (login into Alphastation).

I append a class, which simplifies a telnetsession, posted by Jeffrey
Kunce to this list.

Hope this helps,

__Janko

#### Cut here ####
#!/usr/env/python
#
"""\
python-controlled telnet sessions
tnsessn.py
jjk 04/04/98 001 generalize, from os2telnet.py 001

This module wraps the standard library module telnetlib.py
in a TelnetSession class which automates the login process,
sending commands and retrieving input.

For different host configurations, it is best to
subclass TelnetSession, and write a new _setPlatformStrings()
method (see sample subclasses below)

Example usage:

import tnsessn
session = tnsessn.TelnetSession(hostname, userid, passwd) #connects to host
loginDirectoryListing = session.sendCommand('ls -l') #sends command, captures results
session.close() #closes session

See test() below for more examples

possible problem: Sometimes after multiple telnet sessions in a single python
session, new sessions won't connect right. maybe a port is hung up or something?

THIS CODE IS FOR DEMONSTRATION ONLY. USE AT YOUR OWN RISK!
Jeff Kunce, kun...@mail.conservation.state.mo.us
"""

from telnetlib import Telnet

TraceFlag = 1

class TelnetSession:
"""a basic Telnet Session for unix hosts
jjk 04/04/98"""

def __init__(self, hostname, userid, passwd, timeout=10, trace=0):
"""public: initialize an instance of the receiver
jjk 04/04/98"""
self.hostname = hostname
self.timeout = timeout
if trace:
self.TraceFlag = trace
else:
self.TraceFlag = 0

self._setPlatformStrings()
self._connect(userid, passwd)

def _setPlatformStrings(self):
"""private: defines the various platform-dependent prompt
and command streams necessary for the telnet session.
*** subclass and override for specific hosts ***
jjk 04/04/98"""
self.useridPrompt = 'login: '
self.passwdPrompt = 'Password: '
self.closeCommand = 'exit'
self.loginEndOfLine = chr(10)
self.cmdEndOfLine = chr(10)
# define command prompts
# works best on machines that have more complex prompts than this!
# simple command prompts may interrupt command output containing the prompt
self.cmdPrompt1 = '' # start of command prompt (empty for none)
self.cmdPrompt2 = '$ ' # end of command prompt

def _sendCommandLine(self, cmdStr):
"""private: send a command string with proper line end
jjk 04/04/98"""
self.tnsession.write('%s%s'%(cmdStr, self.cmdEndOfLine))

def _sendLoginLine(self, loginStr):
"""private: send a login string with proper line end
jjk 04/04/98"""
self.tnsession.write('%s%s'%(loginStr, self.loginEndOfLine))

def close(self):
"""public: close the connection
jjk 04/04/98"""
if self.TraceFlag: print 'closing telnet session'
self._sendCommandLine(self.closeCommand)
del self.tnsession
if self.TraceFlag: print 'telnet session closed'

def sendCommand(self, aCommand):
"""public: send a command to the host, answer the results including
the next prompt.
jjk 04/04/98"""
if self.TraceFlag: print 'aCommand:',aCommand
self._sendCommandLine(aCommand)
if self.TraceFlag: print 'waiting'
res = self._waitForPrompt()
if self.TraceFlag: print 'res len:',len(res)
return(res)

def sendCommands(self, commandList = []):
"""public: send commands to the host, answer list of results
jjk 02/27/98"""
resLst = []
for cmd in commandList:
resLst.append(self.sendCommand(cmd))
return(resLst)

def _connect(self, userid, passwd):
"""private: connect to the host
jjk 04/04/98"""
if self.TraceFlag: print 'connect'
self.tnsession = Telnet(self.hostname)
if self.TraceFlag: print 'login'
self.tnsession.read_until(self.useridPrompt, self.timeout)
self._sendLoginLine(userid)
self.tnsession.read_until(self.passwdPrompt, self.timeout)
self._sendLoginLine(passwd)
if self.TraceFlag: print 'waiting'
self._waitForPrompt()
if self.TraceFlag: print 'connected'

def _waitForPrompt(self):
"""private: wait for telnet prompt
Answers all data up to and including prompt.
jjk 04/04/98"""
if self.cmdPrompt1:
res1 = self.tnsession.read_until(self.cmdPrompt1, self.timeout)
else:
res1 = ''
res2 = self.tnsession.read_until(self.cmdPrompt2, self.timeout)
return(res1+res2)

class Web6TelnetSession(TelnetSession):
"""a class to connect to host web6 (SunOS 5.6)
jjk 04/04/98"""

def _setPlatformStrings(self):
"""private: defines the various platform-dependent prompt
and command streams necessary for the telnet session.
jjk 04/04/98"""
TelnetSession._setPlatformStrings(self)
# command prompt is: web6:path#
self.cmdPrompt1 = 'web6:'
self.cmdPrompt2 = '# '

class Os2TelnetSession(TelnetSession):

def __init__(self, hostname, passwd, timeout=10):
"""public: initialize an instance of the receiver
jjk 04/04/98"""
TelnetSession.__init__(self, hostname, '', passwd, timeout)

def _setPlatformStrings(self):
"""private: defines the various platform-dependent prompt
and command streams necessary for the telnet session.
jjk 04/04/98"""
TelnetSession._setPlatformStrings(self)
self.passwdPrompt = 'password:'
self.cmdEndOfLine = chr(13)+chr(10)
# command prompt is: [<hostname>-currentpath]
self.cmdPrompt1 = '[<%s>'%self.hostname
self.cmdPrompt2 = ']'

def _connect(self, userid, passwd):
"""private: connect to the host - OS/2 doesn't use userid
jjk 04/04/98"""
if self.TraceFlag: print 'connect'
self.tnsession = Telnet(self.hostname)
if self.TraceFlag: print 'login'
self.tnsession.read_until(self.passwdPrompt, self.timeout)
self._sendLoginLine(passwd)
if self.TraceFlag: print 'waiting'
self._waitForPrompt()
if self.TraceFlag: print 'connected'

def test(testClass=TelnetSession):
"""test a specific TelnetSession subclass
jjk 04/04/98"""
#from mocons.utils import conuint
print 'TESTING tnsessn.py. class = ', testClass.__name__
host = raw_input('host name: ')
if (testClass!=Os2TelnetSession):
userid = raw_input('login userid: ')
#passwd = conuint.password_input() #raw_input with asterisk echoes (NT only)
passwd = raw_input('password name: ')
if (testClass!=Os2TelnetSession):
tn = apply(testClass,(host, userid, passwd, 10, 1))
cmds = ['pwd', 'ls', 'ps']
else:
tn = apply(testClass,(host, passwd))
cmds = ['dir c:', 'pstat']
res = tn.sendCommands(cmds)
tn.close()
print 'RESULTS: '
for i1 in range(len(cmds)):
print 'COMMAND: %s LENGTH OF RESULTS:%d'%(cmds[i1],len(res[i1]))
raw_input('press Enter to display results')
print res[i1]

if (__name__=='__main__'):
import pdb
#test(Web6TelnetSession)
test(TelnetSession)
#test(Os2TelnetSession)

--
Institut fuer Meereskunde phone: 49-431-597 3989
Dept. Theoretical Oceanography fax : 49-431-565876
Duesternbrooker Weg 20 email: jha...@ifm.uni-kiel.de
24105 Kiel, Germany

Philippe Tempel

unread,
Jan 5, 1999, 3:00:00 AM1/5/99
to
Janko Hauser wrote:
>
> I have tried to run the code and see at first glance no error, besides
> the linedelimiter. I think '\012' ('\n') are enough. If I change your
> last lines from
>
> tn.write('df\r\n');
> print tn.read_all()
>
> to
>
> tn.write('df\n');
> print tn.read_until("prompt", max_wait)
>
> everything functions fine (login into Alphastation).
>
> I append a class, which simplifies a telnetsession, posted by Jeffrey
> Kunce to this list.
>
> Hope this helps,

[...]

Thanks for the class. I'll check it out tonight. BTW, have you
(or anyone else) used the Python-Expect and EventLoop classes
to automate telnet sessions? Just curious if they are any easier
or more complete than telnetlib and telnetsession. I have also
looked at the expy utility on the Expect web page, but it looks
like it is fairly old (it references Python 1.3 in it's source).
It also is just a wrapper around the Expect/Tcl library routines.

The overall motivation for this is that this would be the first
piece of code to telnet into a Unix box, gather some data and
store it into a database like PostgreSQL or MySQL. Then I could
access the info with ODBC and Microsoft Access, Python and CGI
on a web page or some custom GUI that uses Python and database
access libs.

Philippe Tempel

unread,
Jan 5, 1999, 3:00:00 AM1/5/99
to
Jeffrey C. Ollie wrote:
>
> In article <36915AF9...@erols.com>, Philippe Tempel
> <tem...@erols.com> wrote:
> > [...]
> > tn.write(user_passwd)
> > tn.read_until("prompt", max_wait)
> ^^^^^^^^
> > tn.write('df\r\n');
> > print tn.read_all()
> > tn.close()
> >
> > Has anyone used this module yet? The program runs but seems to
> > hang in limbo for a while.
>
> Try removing the quotes from around the reference to the variable
> prompt.

Thanks for pointing this out. I definately didn't mean to have
quotes around the variable... ;-(

Janko Hauser

unread,
Jan 6, 1999, 3:00:00 AM1/6/99
to
Sorry, that I haven't seen the prompt error. It functions because of
the timeout (max_wait) but took some time :-)

Philippe Tempel <tem...@erols.com> writes:
> [...]
>
> Thanks for the class. I'll check it out tonight. BTW, have you
> (or anyone else) used the Python-Expect and EventLoop classes
> to automate telnet sessions? Just curious if they are any easier
> or more complete than telnetlib and telnetsession. I have also
> looked at the expy utility on the Expect web page, but it looks
> like it is fairly old (it references Python 1.3 in it's source).
> It also is just a wrapper around the Expect/Tcl library routines.
>

I haven't worked with soemthing expect like. But if I see your
following needs I don't see, what expect would help. Expect is AFAIK
good for otherwise interactive sessions. But you want to program
something, which is already automatic (I think the data gathering is
programmable, right?)


> The overall motivation for this is that this would be the first
> piece of code to telnet into a Unix box, gather some data and
> store it into a database like PostgreSQL or MySQL. Then I could
> access the info with ODBC and Microsoft Access, Python and CGI
> on a web page or some custom GUI that uses Python and database
> access libs.

If you use Python to gather the data think of writing a class wherein
you store the data, pickle this class, together with access methods
for the data and send the pickled data over an ftp-line. This would
prevent you from ASCII-parsing. (if the data is a little bit more
complex than some lines of numbers)

If the gathering happens often build a socketserver which can be asked
for some pickled data. There is an example in the Python distribution
for an remote Python server. See $PYHOME/Demo/pdist/README Than you
can access the info directly from the CGI, or ... as you like it :-0

__Janko

Red Hat Linux User

unread,
Jan 18, 1999, 3:00:00 AM1/18/99
to
Yeah,
I have used the library and I have'nt had any problems yet. Perhaps a
few print statements will let you see where it is hanging.


Philippe Tempel wrote:

> I'm currently learning Python and want to write a small script
> that uses the telnetlib module to automate logging into a Unix
> box. Here's the script so far:
>
> # Test script for the Python telnetlib.
> #
> # This script will test the Python telnetlib interface by running
> # a simple unix command on the remote machine and printing the
> # results.
> #
>
> from telnetlib import Telnet
>
> max_wait = 30 # set the timeout value
> prompt = ']$' # set the prompt string
> user_login = 'joeblow\r\n' # the username to login with
> user_passwd = 'letMEin\r\n' # the password for the user
>
> tn = Telnet('10.1.1.4') # connect using port 23 (default)
> tn.read_until("login:", max_wait)
> tn.write(user_login)
> tn.read_until("Password:", max_wait)

> tn.write(user_passwd)
> tn.read_until("prompt", max_wait)

> tn.write('df\r\n');
> print tn.read_all()
> tn.close()
>
> Has anyone used this module yet? The program runs but seems to

Evan Simpson

unread,
Jan 18, 1999, 3:00:00 AM1/18/99
to
If this is your actual code, then I think I see your problem...

>> prompt = ']$' # set the prompt string

...
>> tn.read_until("prompt", max_wait)
...

Notice the quotes around 'prompt'. Is that what you really meant?

Mmmm... name/use confusions
Evan Simpson

0 new messages