how to check if the Expect->spawn($command) is success?

243 Views Asked by At

I am passing an scp command in Expect->spawn($command), I am also passing the password or password + OTP based on a $object->expect(). Could you let me know if there is a way to determine if the command has been run successfully ?

I'm trying $object->after() , but it's giving the password prompt which is the previous $object->expect() also explored $object->exitstatus() , it'll be empty since the object is not exited.

my $expect_obj = new Expect;
 $expect_obj->log_stdout(0);
 my $spawn = $expect_obj->spawn(split/\s+/, "scp $src $dest");
 my $pos = $expect_obj->expect(60,
                           [qr/password.*: $/, sub {my $self = shift; $self->send("$pass\n")}],
                        );

How do I determine if the command is successful ?

1

There are 1 best solutions below

2
On

How do I determine if the command is successful ?

You can use waitpid as shown in this answer. It will assign the exit code of the child to $? ($CHILD_ERROR), see more information in perlvar. Here is an example:

use feature qw(say);
use strict;
use warnings;
use Expect;

my $pass = 'my_password';
my $src = 'a_file.txt';
my $dest = '[email protected]:';
my $port = 2222;
my @params = ('-P', $port, $src, $dest);
my $expect = Expect->new();
$expect->log_stdout(0);
my $spawn = $expect->spawn("scp", @params) or die "Cannot spawn scp: $!\n";
my $child_pid = $expect->pid();
my ($pos, $error, $match, $before, $after) = $expect->expect(
    60,
    [qr/password.*: $/, sub {my $self = shift; $self->send("$pass\n")}],
);
my $res = waitpid $child_pid, 0;
if ($res == $child_pid) {
    my $exit_code = $? >> 8;
    if ($exit_code == 0) {
        say "scp exited successfully";
    }
    else {
        say "scp failed with exit code $exit_code";
    }
}
elsif ($res == -1) {
    say "Child process $child_pid does not exist";
}
else {
    say "Unexpected: waitpid() return unknown child pid: $res";
}