У меня вопрос относительно анализа аргументов командной строки и использования команды shift в Perl.

Я хотел использовать эту строку для запуска своего Perl-скрипта

/home/scripts/test.pl -a --test1 -b /path/to/file/file.txt

Итак, я хочу проанализировать аргументы командной строки. Это часть моего сценария, где я это делаю

if ($arg eq "-a") {
    $main::john = shift(@arguments);
} elsif ($arg eq "-b") {
    $main::doe = shift(@arguments);
}

Затем я хочу использовать эти аргументы в переменной $command, которая будет выполнена позже

my $var1=$john;
my $var2=$doe;
my $command = "/path/to/tool/tool --in $line --out $outputdir $var1 $var2";
&execute($command);

Вот две проблемы, с которыми я сталкиваюсь:

Не обязательно указывать -a & amp; -b в командной строке. Но теперь происходит следующее: когда я не указываю -a, я получаю сообщение о том, что я использую неинициализированное значение в строке, где определена переменная.

Вторая проблема: $var2 теперь будет равно $doe, поэтому в данном случае он будет /path/to/file/file.txt. Однако я хочу, чтобы $var2 было равно --text /path/to/file/file.txt. Где я должен указать это --text. Это не может быть стандартно в $command, потому что тогда возникнет проблема, если я не укажу -b. Следует ли мне это делать, когда я определяю $doe, но как тогда?

2
user1987607 2 Май 2016 в 14:07

2 ответа

Лучший ответ

Вы должны построить свою командную строку в соответствии с содержимым переменных

Как это

my $var1 = $john;
my $var2 = $doe;
my $command = "/path/to/tool/tool --in $line --out $outputdir";

$command .= " $var1"        if defined $var1;
$command .= " --text $var2" if defined $var2;

execute($command);

Также

  • Не используйте амперсанды & при вызове подпрограммы Perl. Это не было хорошей практикой вот уже восемнадцать лет

  • Не используйте переменные пакета, такие как $main:xxx. Лексические переменные (объявленные с помощью my) - это почти все, что необходимо

  • Как Альнитак говорит в комментарии вам действительно следует использовать модуль Getopt::Long, чтобы избежать ошибок в синтаксический анализ командной строки

4
Community 23 Май 2017 в 12:23

GetOpt :: Long может быть вариантом: http: / /search.cpan.org/~jv/Getopt-Long-2.48/lib/Getopt/Long.pm

Что касается вашего образца:

Вы не сказали, что должно произойти, если -a или -b отсутствуют, но значения по умолчанию могут решить вашу проблему:

# Use 'join' as default if $var1 is not set
my $var1 = $john // 'john';
# Use an empty value as default if $var2 is not set
my $var2 = $doe // '';

Что касается префикса --text:

Вы хотите установить его всегда?

my $command = "/path/to/tool/tool --in $line --out $outputdir $var1 --text $var2";

Или вы хотите установить его, если было установлено -b = $var2?

# Prefix
my $var2 = "--text $john";

# Prefix with default
my $var2 = defined $john ? "--text $john" : '';
# Same, but long format
my $var2 = ''; # Set default
if ($john) {
    $var2 = "--text $john";
}
0
Sebastian 2 Май 2016 в 11:31