SapphireGirl
asked on
How do I use Expect to execute a system command on a remote server in Perl
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.
Does anyone have a good example of using Expect in a Perl function?
Thank you.
ASKER
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->tang oReportFil e);
}
$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();
}
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->tang
}
$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();
}
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.
$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.
ASKER
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/Exp ect.pm line 182.
I must not be using the $exp->exp_init() method correctly.
I passed it an open FH.
Attempt to bless into a reference at /usr/lib/perl5/vendor_perl
I must not be using the $exp->exp_init() method correctly.
I passed it an open FH.
ASKER
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.
1. Just STDOUT (printing to the screen) or
2. Write it to a Report File.
ASKER
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.
Does that make sense. I did not want to use backticks and capture the response.
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?
What are you trying to do?
ASKER
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.
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.
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
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
ASKER
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
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
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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?
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.
In general - if I had an external program with which I needed to interact.
http://search.cpan.org/~rgiersig/Expect-1.21/Expect.pod
Is this what you are talking about?