0

当我传递一个无效的文件名时,为什么这个脚本继续运行而不死?

#!/usr/bin/env perl
use warnings;
use 5.12.0;
use Getopt::Long qw(GetOptions :config bundling);

sub help {
    say "no help text";
}

sub read_config {
    my $file = shift;
    open my $fh, '<', $file or die $!;
    say <$fh>;
    close $fh;
}

sub helpers_dispatch_table {
    return {
        'h_help'                => \&help,
        'r_read'                => \&read_config,
    };
}

my $file_conf = 'does_not_exist.txt';
my $helpers = helpers_dispatch_table();

GetOptions (
    'h|help'            => sub { $helpers->{h_help}(); exit; },
    'r|read'            => sub { $helpers->{r_read}( $file_conf ); exit },
);

say "Hello, World!\n" x 5;
4

2 回答 2

4

perldoc Getopt::Long

   A trivial application of this mechanism is to implement options that are related to each other. For example:

       my $verbose = '';   # option variable with default value (false)
       GetOptions ('verbose' => \$verbose,
                   'quiet'   => sub { $verbose = 0 });

   Here "--verbose" and "--quiet" control the same variable $verbose, but with opposite values.

   If the subroutine needs to signal an error, it should call die() with the desired error message as its argument. GetOptions() will catch the die(),
   issue the error message, and record that an error result must be returned upon completion.
于 2012-05-01T07:51:34.547 回答
1

问题源于您尝试混合两个任务,以及不检查 GetOptions 是否发现任何错误。

实际上,修复任何一个错误都可以解决您的问题,但以下是解决这两个问题的方法:

sub help {
   # Show usage
   exit(0);
}

sub usage {
   my $tool = basename($0);
   print(STDERR "$_[0]\n") if @_;
   print(STDERR "Usage: $tool [OPTIONS] FILE ...\n");
   print(STDERR "Try `$tool --help' for more information.\n");
   exit(1);
}

my $opt_read;
GetOptions (
    'h|help' => \&help,
    'r|read' => \$opt_read,
) or usage("Invalid arguments");

my $config = read_config($opt_read);
于 2012-05-01T17:15:04.433 回答