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";
2
  • 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? Commented Sep 3, 2012 at 9: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. Commented Sep 3, 2012 at 15:15

4 Answers 4

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) );
Sign up to request clarification or add additional context in comments.

Comments

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?

Comments

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.

Comments

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.