2013-05-27 24 views
2

我的腳本從文本文件中獲取各種參數的一堆值,並將它們放入變量中。然後,運行以下行來執行帶有各種選項的shell命令:如何刪除在perl中運行的shell命令的未使用參數?

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

但是,我應該如何處理一些參數未定義的情況?說-c是可選的,因此用戶在文本文件中將其留空。現在,如果代碼運行,它會做

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

這給出了一個錯誤,因爲-c需要一個參數。如果沒有執行if語句來考慮變量定義的每種可能情況,是否有一種乾淨的方法來處理這個問題?

謝謝。

+0

爲什麼不使用'Getopt :: Std'模塊? –

+0

參數不是通過命令行直接發送到perl腳本,而是一個文本文件包含所有參數。這不是我的代碼,我需要在它上面添加這個特性,因爲我們將使用可選參數。 – gravitas

回答

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 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"); 
} 
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`; 
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` 
+0

'shell_quote'使得它不會失敗,如果任何參數包含空格或另一個shell元字符。 – ikegami

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; 
相關問題