3

Is there a way to force the use of -flags when reading in command-line arguments using Getopt::Long? For example in my current situation:

GetOptions('r=s' => \$var1,
              'lf=f' => \$var2,
              'uf=f' => \$var3,
              'trd=i' => \$var4,
              'vd=f' => \$var5)
or die("$usage");

The script does not exit or display $usage if the arguments are still provided but without the flags (such as -lf). Instead it runs regardless until it inevitably errors later on as the arguments were not read into their respective variables (and may well be in the wrong order).

AnnaSchumann
  • 1,261
  • 10
  • 22
  • It's unclear what you mean by "flags". if you run your code above with just `-lf` as an option then `GetOptions` will return an error status. Do you mean you want some of the options to be mandatory? – Borodin Sep 07 '16 at 14:40
  • @Borodin By flags I mean -lf, -uf, -trd and -vd. I can run the script without a false result by: script.pl arg1 arg2 arg3 arg4. It was my expectation that this would fail to run as this was not provided: script.pl -lf arg1 -uf arg2 -trd arg3 -vd arg4. – AnnaSchumann Sep 07 '16 at 14:58

3 Answers3

4

Q: GetOptions does not return a false result when an option is not supplied

A: That's why they're called 'options'.

Source: Getopt::Long documentation

You could add conditionals to check value of flags and if they are not defined then call die or call usage.

Chankey Pathak
  • 21,187
  • 12
  • 85
  • 133
1

Getopt::Long will search for all the command line options that you specify in the GetOptions call. None of them are required, but an individual option may be required to have a value of a specific type, and GetOptions will return a false status if a value is missing or has the wrong type

Any options and their values are removed from the command line, and anything that is left is passed to the program through @ARGV as normal

Most programs don't require all of the possible options to be provided on the command line, so if you want to insist that all are specified then you can simply test them with

use List::Util 'all';

die $usage unless all { defined } $var1, $var2, $var3, $var4, $var5;

You may also want to require that there is no input which isn't specified as one of the options, in which case you can just check @ARGV

die $usage if @ARGV;
Borodin
  • 126,100
  • 9
  • 70
  • 144
0

Just check afterwards.

use File::Basename qw( basename );

sub help {
    print(...);
    exit(0);
}

sub usage {
   if (@_) {
      my ($msg) = @_;
      chomp($msg);
      warn("$msg\n");
   }

   my $prog_name = basename($0);

   warn("Use $prog_name --help for more information\n");
   exit(1);
}

my ($var1, $var2, $var3, $var4, $var5);

GetOptions(
   'help|h|?' => \&help,
   'r=s'      => \$var1,
   'lf=f'     => \$var2,
   'uf=f'     => \$var3,
   'trd=i'    => \$var4,
   'vd=f'     => \$var5
)
    or usage();

defined($var2)
   or usage("-lf must be provided");
ikegami
  • 367,544
  • 15
  • 269
  • 518