Reputation: 534
I'm running script A which feeds ARGV containing the path to a file to perl script B. This is done by a
local @ARGV = ($file, $file2, etc.);
do scriptB.pl or die "scriptB has failed";
Script B then tries to open the file:
open( my $fh_file, "<", $file )
or die "Could not open file '$file' $!";
However, if the file is missing I do not get the message quoted after "or die" in B. Instead I get the do scriptB.pl or die message in A. If I remove the "or die" from A, the script continues after B silently dies as if nothing went wrong.
I was wondering if there was any way to get B to print its die message?
Better yet, what is the best way to have B run a block of code after it fails to open the file? Said code would for example write to a separate file listing which files were missing so that the user may easily track down such errors.
#something like
open( my $fh_file, "<", $file) or {
print "the file could not be found";
die;
}
The only thing I've found searching the net for help was someone mentioning a "or do {}", but this is giving me strange syntax errors so I am not sure if I'm using it right.
Upvotes: 6
Views: 2287
Reputation: 386696
die
doesn't print a message; die
throws an exception. When you catch that exception you don't do anything with the message passed to die
. Replace
local @ARGV = ($file, $file2, etc.);
do scriptB.pl or die "scriptB has failed";
with
local @ARGV = ($file, $file2, etc.);
do scriptB.pl or die "scriptB has failed: ". ( $@ || $! );
Upvotes: 1
Reputation: 22294
I think you'll get clearer code with fewer gotchas if you put script B into a module, and load it with use
or require
and call the function(s) in there directly with clear parameters.
What you're missing here is that do
involves an eval
behind the scenes, and that results in the exception confusion. You can more or less avoid that confusion by moving your script B code into a function in a module, and calling it.
(Also, perl 5.26 will have a slight hiccup with do
wherein the current directory will be removed from the directory lookup, due to security concerns. use
and require
have the same hiccup, but this may be less surprising since you should put your module into a path you explicitly get into the @INC
load path.)
Upvotes: 1
Reputation: 69314
If you want to continue to use the open(...) or ...
syntax, then you could use do
.
open my $fh, '<', $file or do {
...
};
But I think it's probably clearer to switch to if
if (! open my $fh, '<', $file) {
...
}
Or even unless
unless (open my $fh '<', $file) {
...
}
Upvotes: 9