2017-07-02 42 views
2

我必須在Perl文件中運行函數,並將參數傳遞給函數。Perl將參數從Bash傳遞到文件中

# program.pm 

sub go 
{ 
    # I need to use arguments here 
    # print foo 
    # print bar 
} 

my %functions = (
    go => \&go 
); 

my $function = shift; 

if (exists $functions{$function}) { 
    $functions{$function}->(); 
} else { 
    die "There is no function called $function available\n"; 
} 

這需要運行並通過bash傳遞。我需要能夠隨機指定指定參數時,是這樣的:

$ perl program.pm go foo='bar' bar='fubar'

我非常熟悉的Perl。我在谷歌搜索周圍,不能爲我的生活弄清楚如何正確解析這些。似乎有4種不同的方法可以做到這一點,而且沒有一種方法適合我的用例。

我想這無濟於事還有:

$ perl program.pm -e 'go(foo=>"bar")'

+0

[如何可以解析的命令行參數?](https://stackoverflow.com/questions/3972955/how-can-i-parse-command-line-arguments) –

回答

1

您可以「包括」 program.pm到你的「一個班輪」使用require

殼/ bash腳本

perl -e 'require "/path/program.pm" ; &go(1=>2)' 

program.pm

sub go 
{ 
    # sample subroutine 

    # print subroutine parameters 
    print "go-params: @_\n"; 
    # convert subroutine parameters into hash 
    my %hash = @_; 
    print "go-hash-1: $hash{1}\n" 
} 
# IMPORTANT: indicate proper module initialization 
1; 
+0

輝煌,感謝的可能的複製非常。 – dthree

+1

爲什麼你需要程序而不是運行它?子程序調用的'&'是怎麼實現的? –

+0

@DaveCross 1)要求應該在「一行代碼」中提供**程序中定義的許多子程序**。 2)在這種情況下'&'不需要調用'go'子程序。這是我喜歡的風格指南。 3)你的回答是「更好和推薦的風格」。我的答案是「短代碼」,使程序中定義的子程序的使用變得複雜得多。pm – AnFi

4

你已經接受了答案似乎相當複雜。只需對現有代碼進行一些更改即可。

sub go 
{ 
    # I need to use arguments here 
    # print foo 
    # print bar 
    print "In go\nArgs are: @_\n"; 
} 

my %functions = (
    go => \&go 
); 

my $function = shift; 

if (exists $functions{$function}) { 
    # Pass remaining command-line args to the called subroutine 
    $functions{$function}->(@ARGV); 
} else { 
    die "There is no function called $function available\n"; 
} 

我已經把print()呼叫go()(所以我知道它被稱爲)和我通過@ARGV在調度表中找到的子程序。

你可以像其他任何Perl程序一樣調用它。

$ perl program.pm go foo=bar bar=fubar 
In go 
Args are: foo=bar bar=fubar 

$ perl program.pm XX foo bar 
There is no function called XX available 

更新:在評論中加入這樣的要求:

但我怎麼值分成散列?

有兩個答案。你選擇哪一個取決於你實際想要做什麼。

如果你只是想採取任何「富=酒吧」字符串,並將其解析爲存儲在哈希鍵/值對,那麼你可以用這樣的代碼替換go()子程序:

use Data::Dumper; 

sub go 
{ 
    # I need to use arguments here 
    # print foo 
    # print bar 

    my %args = map { split /=/ } @_; 

    print "In go\nArgs are: " . Dumper(\%args) . "\n"; 
} 

那麼你得到這樣的輸出:

$ perl program.pm go foo=bar bar=fubar 
In go 
Args are: $VAR1 = { 
      'bar' => 'fubar', 
      'foo' => 'bar' 
     }; 

如果你實際上是試圖解析命令行選項,那麼你應該使用命令行選項解析器像GetOpt::Long

use Data::Dumper; 
use Getopt::Long 'GetOptionsFromArray'; 

sub go 
{ 
    # I need to use arguments here 
    # print foo 
    # print bar 

    my %args; 

    GetOptionsFromArray(\@_, \%args, 'foo=s', 'bar=s'); 

    print "In go\nArgs are: " . Dumper(\%args) . "\n"; 
} 

需要注意的是這個工作,你需要通過與--啓動適當的Unix風格的選項。

$ perl program.pm go --foo=bar --bar=fubar 
In go 
Args are: $VAR1 = { 
      'bar' => 'fubar', 
      'foo' => 'bar' 
     }; 

但這個版本是迄今爲止在其輸入的要求,更靈活:

$ perl program.pm go --f bar --b fubar 
In go 
Args are: $VAR1 = { 
      'bar' => 'fubar', 
      'foo' => 'bar' 
     }; 

如果你正在使用無效選項的名稱,它會告訴你。

$ perl program.pm go --fu=bar --baz=fubar 
Unknown option: fu 
Unknown option: baz 
In go 
Args are: $VAR1 = {}; 
+0

但是,我如何將值分成一個散列? – dthree

+0

哦。我很抱歉沒有發現一個你不認爲在你的問題中提到的要求:-) –

+0

哈哈對不起!我喜歡你的方式更好,如果有一些容易的解析它們。 – dthree