Recipe 18.6 Simulating Telnet from a Program
18.6.1 Problem
You want to simulate a
telnet connection from your program by logging
into a remote machine, issuing commands, and reacting to what is
returned. This has many applications, from automating tasks on
machines you can telnet to but which don't support scripting or
rsh, to simply testing whether a machine's
Telnet daemon is still running properly.
18.6.2 Solution
Use the CPAN module Net::Telnet:
use Net::Telnet;
$t = Net::Telnet->new( Timeout => 10,
Prompt => '/%/',
Host => $hostname );
$t->login($username, $password);
@files = $t->cmd("ls");
$t->print("top");
(undef, $process_string) = $t->waitfor('/\d+ processes/');
$t->close;
18.6.3 Discussion
Net::Telnet provides an object-oriented interface to the Telnet
protocol. Create a connection with
Net::Telnet->new, then interact with the remote
machine using method calls on the resulting object.
Give the new method a list of named-parameter
pairs, much like initializing a hash. We'll cover only a few possible
parameters. The most important is Host, the
machine you're telnetting to. The default host is
localhost. To connect to a port other than the one
Telnet normally uses, specify this in the Port
option. Error handling is done through the function whose reference
is specified in the Errmode parameter.
Another important option is Prompt. When you log
in or run a command, Net::Telnet uses the Prompt
pattern to determine when the login or command has completed. The
default Prompt is:
/[\$%#>] $/
which matches the common Unix shell prompts. If the prompt on the
remote machine doesn't match the default pattern, you have to specify
your own. Remember to include slashes.
Timeout lets you control how long (in seconds)
network operations wait before they give up. The default is 10
seconds.
An error or timeout in the Net::Telnet module raises an exception by
default, which, if uncaught, prints a message to
STDERR and exits. To change this, pass
new a subroutine reference to the
Errmode argument. If instead of a code subroutine
you specify the string "return" as the
Errmode, methods return undef
(in scalar context) or an empty list (in list context) on error, with
the error message available via the errmsg method:
$telnet = Net::Telnet->new( Errmode => sub { main::log(@_) }, ... );
The login method sends a username and password to
the remote machine. It uses the Prompt to decide
when the login is complete and times out if the machine doesn't reply
with a prompt:
$telnet->login($username, $password)
or die "Login failed: @{[ $telnet->errmsg( ) ]}\n";
To run a program and gather its output, use the
cmd method. Pass it the string to send; it returns
the command output as one line per list element in list context, or
as one long line in scalar context. It waits for the
Prompt before returning.
Separate sending the command from reception of its output with the
print and waitfor methods, as
we do in the Solution. The waitfor method takes
either a single string containing a Perl regular expression in
slashes:
$telnet->waitfor('/--more--/')
or named arguments. Timeout specifies a timeout to
override the default, Match is a string containing
a match operator as shown earlier, and String is a
literal string to find:
$telnet->waitfor(String => 'greasy smoke', Timeout => 30)
In scalar context, waitfor returns true if the
pattern or string was found. Otherwise, the
Errmode action is performed. In list context, it
returns two strings: any text before the match and the matching text
itself.
18.6.4 See Also
The documentation for the Net::Telnet module from CPAN; RFCs 854-856,
as amended by later RFCs
|