2009-02-20 20 views
13

如何在Perl的system()命令中使用bash語法?如何在Perl的系統()中使用bash語法?

我有一個特定於bash的命令,例如,下面,使用bash的進程替換:

diff <(ls -l) <(ls -al) 

我想從Perl中調用它,使用

system("diff <(ls -l) <(ls -al)") 

,但它給了我一個錯誤,因爲它使用sh代替bash執行命令:

sh: -c: line 0: syntax error near unexpected token `(' 
sh: -c: line 0: `sort <(ls)' 

回答

45

讓Perl直接調用bash。使用list變種system(),以減少你的報價的複雜性:

my @args = ("bash", "-c", "diff <(ls -l) <(ls -al)"); 
system(@args); 

你甚至可以定義一個子程序,如果你打算這樣做往往不夠:與vladr的答案

sub system_bash { 
    my @args = ("bash", "-c", shift); 
    system(@args); 
} 

system_bash('echo $SHELL'); 
system_bash('diff <(ls -l) <(ls -al)'); 
+1

+1使用列表變種 – 2009-02-20 21:57:20

+3

這也可以防止你調用/ bin/sh只是運行bash – cjm 2009-02-20 21:58:03

5
system("bash -c 'diff <(ls -l) <(ls -al)'") 

應該這樣做,在理論上。根據手冊頁,Bash的-c選項允許您傳遞一個shell命令來執行。

4

的問題是,系統不會從命令中捕獲輸出到STDOUT(你通常想要的),也不允許執行多個命令(假設使用移位而不是訪問@_的全部內容)。

類似下面的可能是更適合的問題:

my @cmd = ('diff <(ls -l) <(ls -al)', 'grep fu'); 
my @stdout = exec_cmd(@cmd); 
print join("\n", @stdout); 

sub exec_cmd 
{ 
    my $cmd_str = join(' | ', @_); 
    my @result = qx(bash -c '$cmd_str'); 
    die "Failed to exec $cmd_str: $!" unless($? == 0 && @result); 
    return @result; 
} 

不幸的是這不會阻止你調用/ bin/sh的只是運行bash的,但我沒有看到一個解決辦法這個問題。

0

我更喜歡用反引號「`」在perl中執行bash命令。這樣我得到一個返回值,例如:

my $value = \`ls`; 

此外,我不必使用「bash -c」只是運行一個命令。適用於我。

0

從@ errant.info通過回答啓發,我創造了更簡單的東西,對我的工作:

my $line="blastn -subject <(echo -e \"$seq1\") -query <(echo -e \"$seq2\") -outfmt 6"; 
my $result=qx(bash -c '$line'); 
print "$result\n"; 

引進的$行變量允許修改輸入($ SEQ1和SEQ2 $)各一次。 希望它有幫助!