[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

How do I use Expect to execute a system command on a remote server in Perl

Posted on 2009-04-24
13
Medium Priority
?
792 Views
Last Modified: 2012-05-06
I have used the backtick  but I would like to use the Expect methods.

Does anyone have a good example of using Expect in a Perl function?

Thank you.
0
Comment
Question by:SapphireGirl
  • 7
  • 6
13 Comments
 
LVL 39

Expert Comment

by:Adam314
ID: 24228114
There is an Expect module for perl.  It is documented, and has examples:
    http://search.cpan.org/~rgiersig/Expect-1.21/Expect.pod

Is this what you are talking about?  
0
 

Author Comment

by:SapphireGirl
ID: 24229659
Ok, I got my TestExpect method to work to STDOUT but it does not correctly write to my File.  This is what I did.  Please give my your feedback on whether or not this is the best way to do this.
I basically want a reusable function that I can send any command to when rsh(ing) to a remote server.

sub TestExpect {
  my ($self, $command) = @_;

  my $exp = new Expect;
  if ($PrintReport) {
     $exp->exp_init($self->tangoReportFile);
  }

  $exp->raw_pty(1);
  $exp->spawn($command)
    or die "Cannot spawn $command: $!\n";

# send some string there:
  $exp->send($command);


  if ($PrintReport) {
# or, for the filehandle mindset:
  print $exp $command;


  }
$exp->soft_close();

}
0
 
LVL 39

Expert Comment

by:Adam314
ID: 24229692
I'm not sure what you are trying to do... but this:
    $exp->spawn($command) or die "Cannot spawn $command: $!\n";
    # send some string there:
    $exp->send($command);

Will try to start $command on this server, then send $command to that process.  Is this really what you intended?

What are you trying to do?  If you aren't capturing any of the output, maybe Expect isn't really what you need.
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 

Author Comment

by:SapphireGirl
ID: 24229699
Ok, I set the $PrintReport flag to be 1 and the program chokes with the error

Attempt to bless into a reference at /usr/lib/perl5/vendor_perl/5.8.6/Expect.pm line 182.

I must not be using the $exp->exp_init() method correctly.
I passed it an open FH.

0
 

Author Comment

by:SapphireGirl
ID: 24229712
I would like to capture the output in 2 ways.
1.  Just STDOUT (printing to the screen) or
2.  Write it to a Report File.
0
 

Author Comment

by:SapphireGirl
ID: 24229730
I think I want to be using the Expect Methods because I could be running this TestExpect method in a loop say 64 or 128 times.

Does that make sense.  I did not want to use backticks and capture the response.
0
 
LVL 39

Expert Comment

by:Adam314
ID: 24229816
Why did you not want to use backticks?  Expect is good if you need to look for some particular output, and provide input based on that.  If you just want to capture all of the output, backticks are fine.  If the output is to large to store in a variable all at once (which is what happens with backticks), you might use open with "|", and read/process 1 line at a time.  If you need to read from and write to the process, open2 or open3 might be good.

What are you trying to do?
0
 

Author Comment

by:SapphireGirl
ID: 24230359
Here is what I am trying to do.
1.  rsh into a remote server and check the disk space on 4 of the mounts.
2.  If the ds is greater than 95% on these mounts, I need to email the users of the largest files on that server.
I can hack this out but this is how I want to solve this programming problem.

I want to automate all of this in an elegant solution.
An elegant solution to me is a solution in which I can perform any command line system call, whether it be calling scripts, checking disk space, etc in a perl class.
That is why I am trying  to write the TestExecute method to be a very general function that can be used not only for a system df call but maybe some other systems calls in the future.
This is why I am passing in the Command.
So this time it will be checking disk space and next time I will (lets say) push files on a set of machines.
I did not want to use the backtick because I have read that it could be unreliable.

It seemed like using the Expect functions would be a good way to solve a general problem.

Does that make sense.


0
 
LVL 39

Expert Comment

by:Adam314
ID: 24242960
The backticks are not unreliable if you do not need to provide input to your command.  If, from the command prompt, you can run rsh, and not be asked anything (meaning, the program just runs, and you get your output), then backticks will be just fine.

There are also several perl modules to help you make an ssh connection, and run a program.  You might want to consider one of them.  For a single command, the Net::SSH module makes sense.

If you already have keys setup, and you just want to execute a command, you can use this:
use Net::SSH 'ssh';

my $output = ssh('user@host', 'df');
#Parse $output to determine free disk space,  or use a different command
0
 

Author Comment

by:SapphireGirl
ID: 24254710
Here is my problem though,  I do not know how to parse thru a directory structure using a back tick command.

Ex.  I want to get to machinea and then iteratively go thru the /project directory and all of its sub directories to get a total for lets say userA, userB, and userC.

I don't think I can do it with a ` ` back tick command without having the rsh into the machinea several times.
This would add lots of time and complications if the machine(s) were to go down during the time this script is running.  These methods should be able to thru about 100 machines, each with 4 different mounts, with hundreds of projects on them.  I need to find an solution that is going to be robust and quick.  (Duh, that is what every programmer wants) :0
0
 
LVL 39

Accepted Solution

by:
Adam314 earned 2000 total points
ID: 24254925
>>Ex.  I want to get to machinea and then iteratively go thru the /project directory and all of its
>>sub directories to get a total for lets say userA, userB, and userC.
From what you said... Is this your setup:
   /project/userA
   /project/userB
   /project/userC
You want to find out the disk space used by each of these?  If so, maybe the du command would make it easy.  Or, if you need to look at each file, maybe the find command.  If so, you might be able to do it in a single command.

If you want to log in, and run multiple commands - for this, I use the Net::SSH::Perl module.
    http://search.cpan.org/~turnstep/Net-SSH-Perl-1.34/lib/Net/SSH/Perl.pm
After logged in, you call the cmd method, and it returns to you the standard output, standard error, and exit code for that program.  I find this module easier to use than Expect.  But I'm sure some of this is personal preference.

The backticks allows you to, with a single perl command, execute a single external program, and capture it's output.  If this isn't the way your program will work, then backticks would not be the best solution.

0
 

Author Closing Comment

by:SapphireGirl
ID: 31574355
Thank you Adam,  I will use the back tick, capture the output to a file then parse the file to do what I need to do.  When would you use Expect though?
0
 
LVL 39

Expert Comment

by:Adam314
ID: 24255363
For SSH - I wouldn't, as there are modules specifically designed for SSH that I think are easier to use.
In general - if I had an external program with which I needed to interact.
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction We as admins face situation where we need to redirect websites to another. This may be required as a part of an upgrade keeping the old URL but website should be served from new URL. This document would brief you on different ways ca…
It’s 2016. Password authentication should be dead — or at least close to dying. But, unfortunately, it has not traversed Quagga stage yet. Using password authentication is like laundering hotel guest linens with a washboard — it’s Passé.
Learn several ways to interact with files and get file information from the bash shell. ls lists the contents of a directory: Using the -a flag displays hidden files: Using the -l flag formats the output in a long list: The file command gives us mor…
Learn how to get help with Linux/Unix bash shell commands. Use help to read help documents for built in bash shell commands.: Use man to interface with the online reference manuals for shell commands.: Use man to search man pages for unknown command…
Suggested Courses

873 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question