0

I am adapting a perl backup script from CentOS 6 to Ubuntu 20.04.

The subroutine ExecCmd() starts a child process for a system call to rsync.

On CentOS 6 it populates a variable $ExecCmdOut with the rsync output and returns the exit status, $pipestatus.

On Ubuntu $pipestatus contains the last line of the rsync output. In the log I see

Error (573): rsync failed with status total size is 2,728,691,525  speedup is 509.15.

Here is the function. Can you see why ?

sub ExecCmd( \@$ ) {
    (my $cmdRef, my $forcelog) = @_;
    my @cmd = @$cmdRef;
    my $pipestatus='';
    die "Fork failed: $!\n" unless defined( my $pid=open(RCHILD, "-|"));
    if( $pid ) { 
        $ExecCmdOut='';
        while(<RCHILD>) {
            chomp( $_ );
            next if $_ eq '';
            s/\e\[[0-9\;]+[A-Za-z]//g; # remove ANSI escape sequences
            $ExecCmdOut.="$_\n";
            $pipestatus=$_;
        }
        close( RCHILD );
    } else {
        exec( "@cmd 2>&1; echo \${PIPESTATUS}" ) or die "exec failed: $!\n";
    }
    $ExecCmdOutout =~ s/$pipestatus\n$//;
    $pipestatus =  $? if not $pipestatus;
    return $pipestatus;
}

1 Answers1

0

You populate $pipestatus with the current line here:

$pipestatus=$_;

At the end, you set it to $? only when $pipestatus is false. If it contains the last line, it's not false, so it won't be changed to $?.

choroba
  • 231,213
  • 25
  • 204
  • 289
  • Changing $pipestatus = $? if not $pipestatus; to $pipestatus = $? corrected the call to rsync but broke the other system calls. I got around the problem by creating a copy of sub ExecCmd spesificly for the rsync call. However, all this doesn't explain why it worked on CentOS6 but not Ubuntu 20.04 – Keith Slater Mar 26 '21 at 08:11
  • Try checking what `rsync` returns as the last line on the respective systems. – choroba Mar 26 '21 at 08:16