Принудительное использование флагов Getopt::Long

Есть ли способ принудительно использовать -flags при чтении аргументов командной строки с помощью Getopt::Long? Например, в моей текущей ситуации:

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

Сценарий не завершает работу и не отображает $usage, если аргументы все еще указаны, но без флагов (таких как -lf). Вместо этого он работает независимо до тех пор, пока позже неизбежно не возникнут ошибки, поскольку аргументы не были прочитаны в соответствующие переменные (и вполне могут быть в неправильном порядке).


person AnnaSchumann    schedule 07.09.2016    source источник
comment
Непонятно, что вы имеете в виду под флагами. если вы запустите свой код выше только с -lf в качестве опции, тогда GetOptions вернет статус ошибки. Вы хотите, чтобы некоторые параметры были обязательными?   -  person Borodin    schedule 07.09.2016
comment
@Borodin Под флагами я подразумеваю -lf, -uf, -trd и -vd. Я могу запустить скрипт без ложного результата: script.pl arg1 arg2 arg3 arg4. Я ожидал, что это не запустится, поскольку это не было предоставлено: script.pl -lf arg1 -uf arg2 -trd arg3 -vd arg4.   -  person AnnaSchumann    schedule 07.09.2016


Ответы (3)


Вопрос. GetOptions не возвращает ложный результат, если параметр не указан.

О: Вот почему они называются "вариантами".

Источник: Getopt::Подробная документация

Вы можете добавить условные выражения для проверки значения флагов, и если они не определены, то вызовите die или вызовите usage.

person Chankey Pathak    schedule 07.09.2016

Getopt::Long будет искать все параметры командной строки, указанные вами в вызове GetOptions. Ни один из них не является обязательным, но для отдельного параметра может потребоваться значение определенного типа, и GetOptions вернет статус false, если значение отсутствует или имеет неправильный тип.

Любые параметры и их значения удаляются из командной строки, а все, что осталось, передается в программу через @ARGV как обычно.

Большинство программ не требуют, чтобы все возможные параметры были указаны в командной строке, поэтому, если вы хотите настаивать на том, чтобы все были указаны, вы можете просто проверить их с помощью

use List::Util 'all';

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

Вы также можете потребовать, чтобы не было входных данных, которые не указаны в качестве одной из опций, и в этом случае вы можете просто проверить @ARGV

die $usage if @ARGV;
person Borodin    schedule 07.09.2016

Просто проверь потом.

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");
person ikegami    schedule 07.09.2016