2

My script gets a bunch of values for various arguments from a text file and puts them into variables. Then, the following line is run to execute a shell command with the various options:

cmd -a $a -b $b -c $c ;

However, how should I deal with the case where some arguments are not defined? Say -c is optional and thus the user leaves it blank in the text file. Right now if the code runs it would do

$a = "foo";
$b = "bar"; 
$c = "";
`cmd -a $a -b $b -c $c ` ; # this evaluates to "cmd -a foo -b bar -c" 

which gives an error since -c needs an argument. Without implementing if-statements to consider each possible case for variable definition, is there a clean way to deal with this?

Thanks.

4

4 回答 4

4
use String::ShellQuote qw( shell_quote );

$a = ...;
$b = ...;
$c = ...;

my @cmd = 'cmd';
push @cmd, '-a' => $a if length($a);
push @cmd, '-b' => $b if length($b);
push @cmd, '-c' => $c if length($c);
my $cmd = shell_quote(@cmd);
`$cmd`

如果参数顺序无关紧要,使用散列而不是单独的变量会更有意义。

use String::ShellQuote qw( shell_quote );

my %args = (
   '-a' => ...,
   '-b' => ...,
   '-c' => ...,
);

my @cmd = ( 'cmd', map { $_ => $args{$_} } grep length($args{$_}), keys(%args) );
my $cmd = shell_quote(@cmd);
`$cmd`
于 2013-05-27T19:19:10.157 回答
3

您可以使用哈希,然后过滤掉长度为零的参数,

my %arg = (
  a => $a,
  b => $b,
  c => $c,
);
my $cmd_args = 
  join " ", 
  map { "-$_ $arg{$_}" }
  grep { length $arg{$_} > 0 }
  sort keys %arg;

`cmd $cmd_args`;
于 2013-05-27T19:18:26.527 回答
1

让我说清楚:

  1. 您运行一个 Perl 脚本。
  2. 该 Perl 脚本为命令行脚本获取或创建了一堆选项。
  3. 然后,您可以使用这些选项来运行可执行文件。

我会将您的选项放入 Perl 哈希中,并由命令行参数键入,值将是该命令行参数的值。

my %parameters;
$parameters{"-a"} = "foo";
$parameters{"-b"} = "bar";
$parameters{"-c"} = "";

现在,让我们构建要执行的命令。我将通过keys命令解析数组。%parameters这将在我的循环中返回所有可能散列的键:

my $command = "cmd";

for my $param ( sort keys %parameters ) {
    if ( $parameters{ $param } ) {
        $command .= " $param $parameters{$param}";
    }
}

请注意,$parameters{ $param } is blank or zero, it will not add that parameter/value pair to the command line you're executing. Now, we can execute the command. Use如果您不需要从命令返回任何值,则 if system`。然后检查以确保执行正常:

my $error = system "$command";
if ( $error ) {
    die qq(Error detected in running command "$command");
}

如果参数可能为空、有空格或零值,我们必须采取稍微不同的策略:

my %parameters;
$parameters{"-a"} = "foo";
$parameters{"-b"} = "bar";
$parameters{"-c"} = undef;

my $command = "cmd";

for my $param ( sort keys %parameters ) {
    if ( defined $parameters{ $param } ) {
        $command .= qw/ $param "$parameters{$param}"/;
    }
}

my $error = system "$command";
if ( $error ) {
    die qq(Error detected in running command "$command");
}
于 2013-05-27T19:29:23.037 回答
0

我将使用各种Getopt模块之一来读取命令行并将条目放入变量中。通常,带有参数的选项也将定义一个默认值,或者如果没有给出参数,它将使变量未定义。

当 perl 文件执行时,它将填写变量,然后您可以从这些参数构造命令行,您可以使用如下逻辑:

push @cmd, "mycmd";
push @cmd, "-a", $opta;
push @cmd, "-b", $optb;
push @cmd, "-c", $optc if defined $optc; # Possibly leave out defined.
system @cmd;
于 2013-05-27T19:20:44.783 回答