譯者/作者:qiang
出處:中國Perl協會 FPC(Foundation of Perlchina)
作者:Dave Cross
原名:Perl Command-Line Options
原文:http://www.perl.com/pub/a/2004/08/09/commandline.html
Perl 有很多命令行參數。通過它可以讓你的程序更簡練,并且可以寫出很多只有一行命令的perl。在這篇文章里我們來了解一些常用的命令行參數。
-C 是第一個。這個參數編譯 Perl 程序但并不真正運行它。由此檢查所有語法錯誤。每次修改 perl 程序之后我都會立刻使用它來找到任何語法錯誤。
$ perl -c program.pl這保證了程序依然可以編譯。很顯然,當你輸入一小段代碼之后立即進行檢查,比起一下子輸入幾百行代碼然后開始 debug 要容易很多。
-W 是第二個參數。它會提示你任何潛在的bug。Perl 5.6.0 之后的版本已經用 use warnings; 替換了 -w。你應該使用 use warnings 因為它要比 -w 更靈活。
-T 是第三個參數。它讓 perl 出于了 taint 模式中。在這個模式里,Perl 會質疑任何程序外傳來的數據。例如,從命令行讀取,外部文件里讀取 或是 CGI 程序里傳來的數據。這些數據在 -T 模式里都會被 Tainted(污染)。
Tainted 數據不可以被用來和外部交互。例如 使用在 system 調用和用作 open 的文件名。關于什么數據會被Tainted,請參閱perlsec 文檔,那里有一個完整的列表。
要想使用 Tainted 的數據就必須 untaint這個數據。untaint 是通過正則表達式來實現的,關于 taint 本身的內容足夠寫一篇單獨的文章,所以這里我不會太多的講述 taint 模式。如果你要編寫的程序(例如 CGI 程序)需要從從用戶那里接受不可知的輸入,我推薦使有 taint 模式。
還有一個值得一提的參數是 -d,它將讓 Perl 處于 Debugger 模式。這個話題內容非常多,我推薦閱讀文檔 ‘perldoc perldebug’ 或 Richard Foley 的 Perl Debugger Pocket Reference 一書.
$ perl -e 'print "Hello World\n"'多個 -e 也可以同時使用, 運行順序根據它出現的位置.
$ perl -e 'print "Hello ";' -e 'print "World\n"'象所有的 Perl 程序一樣, 只有程序的最后一行不需要以 ; 結尾.
雖然你也可以用 -e 來引用模塊, 但 -M 讓它變得更容易.
$ perl -MLWP::Simple -e 'print head "http://www.example.com"'-M模塊名 和 use 模塊名 一樣。有些模塊有默認的模塊導入,如果你不想導入它們,你可以使用 -m。-m模塊名 和 use module() 一樣,關閉了默認的導入。例如下面這個例子, 因為 head 函數是默認導入,而使用 -m 時就不會執行,結果是沒有輸出。
$ perl -mLWP::Simple -e 'print head "http://www.example.com"'-m 和 -M 有很多方便的語法來幫助你使用它們,你可以在 = 后面列出對 use 的各種參數。
$ perl -MCGI=:standard -e 'print header'在這里,CGI.pm 的 :standard 被引入,header 函數因此可以使用。要引入多個參數可以通過使用引號和逗號。
$ perl -MCGI='header,start_html' -e 'print header, start_html'這里我們引入了 header 和 start_html 函數。
$ perl -n -e 'some code' file1這與下面的程序一樣.
LINE: while (<>) { # your code goes here }注意: <> 打開命令行里的文件,一行行的讀取。每一行將缺省保存在 $_
$ perl -n -e 'print "$. - $_"' file上面的這一行可以寫成 LINE: while (<>) { print ”$. – $_” } 輸出當前行數 $. 和當前行 $_.
-p 可以讓上面的程序變得更容易.-p 會輸出 $_ 的內容,就像這樣:
LINE: while (<>) { # your code goes here } continue { print or die "-p destination: $!\n"; }continue 在這里保證 print 在每次循環都會被調用。
使用 -p,我們的打印行數程序可以改為
$ perl -p -e '$_ = "$. - $_"'這種情況下我們就不需要要明確地調用 print 函數了,因為 -p 選項已經調用了它。
注意, LINE: 標簽可以讓我們直接跳到下一個輸入記錄,而不管你進入了多少層循環。使用 next LINE。
$ perl -n -e 'next LINE unless /pattern/; print $_'當然,也可以這樣寫:
$ perl -n -e 'print unless /pattern/'在更復雜的情況里, next LINE 可以讓你的代碼更容易理解。
如果想在循環的前后做些處理,可以使用 BEGIN 或 END block. 下面的這一行代碼可以計算 text 文件里的字數。
$ perl -ne 'END { print $t } @w = /(\w+)/g; $t += @w' file.txt每一行所有匹配的字放入數組 @w,然后把 @w 的元素數目遞加到 $t。END block 里的 print 最后輸出文件總字數。
還有兩個參數可以讓這個程序變得更簡單。-a 打開自動分離 (split) 模式??崭袷侨笔〉姆蛛x號。輸入根據分離號被分離然后放入缺省數組 @F。由此,我們可以把上面的程序改寫為
$ perl -ane 'END {print $x} $x += @F' file.txt你也可以通過 -F 把缺省的分離號改為你想要的.例如把分離號定為非字符:
$ perl -F'\W' -ane 'END {print $x} $x += @F' file.txt下面通過 Unix password 文件來介紹一個復雜的例子。Unix password 是文本文件,每一行是一個用戶記錄,由冒號 :分離。 第?行是用戶的登錄 shell 路徑。我們可以得出每一個不同 shell 路徑被多少個用戶使用:
$ perl -F':' -ane '$s{$F[6]}++;' \ > -e 'END { print "$_ : $s{$_}" for keys %s }' /etc/passwd雖然現在不是一行,但是你可以看出使用參數可以解決什么問題。
$/ 和 $\ 可與 -n -p 一起使用。在命令行上相對應為 -0 (零) 和 -l ( 這是 L )。-0 后面可以跟一個16 進制或8進制數值,這個值用來賦給 $/。-00 打開段落模式,-0777 打開slurp 模式 (即可以一次把整個文件讀入),這與把 $/ 設為空字符和 undef 一樣效果。
單獨使用 -l 有兩個效果,第一自動 chomp 輸入分隔號,第二 把$/ 值付給 $\ ( 這樣 print 的時候就會自動在末尾加 \n )
我個人常常使用 -l 參數, 用來給每一個輸出加 \n. 例如
$ perl -le 'print "Hello World"'
$ perl -pe 'some code' < input.txt > output.txt這個程序從 input.txt 讀取數據, 然后做一些處理再輸出到 output.txt. 你當然也可以把輸出重定向到同一個文件里. 上面的程序可以通過 -i 參數做的更簡單些。-i 把源文件更名然后從這個更名的源文件里讀取。最后把處理后的數據寫入源文件。如果 -i 后跟有其他字符串,這個字符串與源文件名合成后來生成一個新的文件名。此文件會被用來儲存原始文件以免被 -i 參數覆蓋。
這個例子把所有 php 字符替換為 perl :
$ perl -i -pe 's/\bPHP\b/Perl/g' file.txt程序讀取文件的每一行, 然后替換字符, 處理后的數據重新寫入( 即覆蓋 ) 源文件. 如果不想覆蓋源文件, 可以使用
$perl -i.bak -pe 's/\bPHP\b/Perl/g' file.txt這里處理過的數據寫入 file.txt , file.txt.bak 是源文件的備份.
Perl 有大量的命令行參數,這篇文章只是列舉了最有用的一小部分。更詳細的信息請參考 “perlrun” 文檔。