2009-11-19 61 views
5

我想寫一個腳本foo,它使用Bash或Perl簡單地調用bar,它與調用的參數完全相同。如何獲取未修改的命令行參數來「換行」另一個命令行工具?

現在,一個簡單的方法在Perl中做到這將是

#!/bin/perl 

my $args=join(' ', @ARGV); 
`bar $args`; 

然而,在ARGV的值已經被shell處理,因此,如果我叫

foo "I wonder, \"does this work\"" 

欄會這樣叫

bar I wonder "does this work" 

如何獲取原始命令行,以便我可以簡單地傳遞它逐字?

回答

11

在shell處理它們之前,您無法獲得perl可執行文件的參數。你可以,但是,確保外殼不處理他們再次

system('bar', @ARGV); 

system("bar @ARGV"); 

perldoc -f system

如果 只有一個標量參數,檢查參數是否爲shell元字符,如果有,則將整個參數傳遞給系統的 用於解析的命令解釋器(這在Unix平臺上是「/ bin/sh -c」,但在其他平臺上有所不同)。如果 參數中沒有shell元字符,則將其分割爲單詞並直接傳遞給「execvp」,這更有效。

如果您需要讀取程序的輸出,使用進程句柄,並以同樣的方式傳遞參數(無插值):

open my $barhandle, '-|', 'bar', @ARGV or die "Can't call bar: $!"; 
while (my $line = <$barhandle>) 
{ 
    # do something with $line... 
} 
close $barhandle; 

有很多可以叫出方式用Perl編寫的程序;請參閱What's the difference between Perl's backticks, system, and exec?以瞭解主要選項的完整概述。

+0

其中一個考慮因素當然是system()的返回值是程序執行的返回值,而不是程序的輸出。如果您要收集輸出,可能需要將輸出重定向到文件並讀取文件。 – atk 2009-11-19 19:13:54

+0

@atk:在這種情況下,您可以使用進程句柄。 – Ether 2009-11-19 19:14:51

+1

不,在這種情況下,你使用IPC :: Run或IPC :: Cmd – ysth 2009-11-19 20:37:10

3

這非常簡單。查看系統調用的系統(LIST)變體。

system('bar', @ARGV); 

的perldoc -f系統

3

在bash:

exec bar "[email protected]" 

這將保留在參數的間距。但是,I/O重定向不是該術語含義內的一個參數(但除非您更改,否則爲原始調用完成的I/O重定向會持續到調用的「bar」命令)。