1

I have a following code, where i use a command which is used as input for file open.

when my command $cmd gives non-zero exit status my script exits. i want it to still continue and do rest of the things in the script

$cmd = 'ps -u psharma';
open( my $fh, "-|",$cmd ) || die( "$cmd failed: $!" );
my @lines = <$fh>;
close($fh) || die $! ? "Close for $cmd failed: $!" : "Exit status $? from command $cmd";
  • Your last die statement is very ambiguous. It looks as it either checks the return value of `die $!` or selects a string as argument to die. Either way, the script still dies if the close fails. How did you expect it not to? – TLP Sep 03 '12 at 09:29
  • i actually wanted to check, whether the error was thrown by the non-zero exit status of $cmd or Close() filehandler. The intension behind doing all this is to make sure the rest part of the script is executed even if exit status of $cmd is non-zero. – Pinky Sharma Sep 03 '12 at 15:15

4 Answers4

1

Instead of using die, try using Carp to warn you that it did not exit successfully. It will still continue the script.

carp ("Did not exit command successfully!\n") if (! close ($fh) );
squiguy
  • 32,370
  • 6
  • 56
  • 63
0

If this is the whole script, then it terminates at the last line if execution of cmd returned non-zero. If you want to continue execution beyond this code, then shouldn't you remove die at the last line?

BSen
  • 187
  • 2
  • 16
0

You can wrap everything in an eval block and check the "magic variable" $@, like so:

use strict; #always
use warnings; #always

my $cmd = 'ps -u psharma';

my $fh; #defining outside the scope of the eval block
my @lines; #ditto

eval {
    open $fh, "-|", $cmd 
        or die "$cmd failed: $!";

    @lines = <$fh>;
    close $fh
        or die $!
               ? "Close for $cmd failed: $!"
               : "Exit status $? from command $cmd";
}

if($@) {

    warn "Something bad happened: $@\n";
}
#If you made it here with no warning, then everything's okay.

You can also check out Try::Tiny, which allows for basic try/catch/finally blocks.

Pavel Vlasov
  • 3,455
  • 21
  • 21
0
close($fh) || die $! ? "Close for $cmd failed: $!" : "Exit status $? from command $cmd";

This code already checks for $!/$? (errno/$cmd exit status). So you can just move die deeper:

close($fh) || $! 
    ? die "Close for $cmd failed: $!" 
    : warn "Exit status $? from command $cmd";

However, I think an explicit if could be more readable here.

Dallaylaen
  • 5,268
  • 20
  • 34