與外界對話
Perl 本身已是一個相當強大的語言; 但是 perl
最大的力量來自於它與外界其他程式溝通的能力.
使用者本來就可以手動令你的 perl 程式與外界溝通,
例如想把目前目錄下所有檔案名稱的大小寫對調, 可以將 ls
的輸出餵給我們先前寫的 rencase 吃, 像這樣:
ls | rencase
又如 count_arg
程式可以拿來數數看目前線上每個人 login 幾次, 像這樣: count_arg
`who -q | grep -v '^#'`
但這需要使用我們程式的人懂得
pipe 或
back quote 等觀念.
本單元要介紹的則是如何從你的 perl 程式 裡面
去執行外界的命令, 讓你的 perl
程式以四兩之力將千斤大問題撥給系統內其他程式去解決.
再收割成果呈現給使用者看, 讓不知情 (或不會自己下 pipe/back quote)
的使用者以為你有多厲害! (其實會發揮
組合的力量 的人,
真的很厲害.)
範例程式: 統計每位使用者上機次數與時間長短
四種基本方式
首先, 如果你只是想執行外部命令, 對這個外部命令產生的訊息並無興趣, 可以用 system 函數來執行外部命令:
system("cp -r $ENV{HOME}/important $ENV{HOME}/backup");
當然, 你也可以用內建模組 File::Copy 做相同的事。
其次, 如果你不但要執行外部命令, 還希望在你的 perl 程式內分析它的結果, 那麼就用 back quote 來執行外部命令, 一口氣把它印出來的所有資料讀入一個陣列. 外部命令所印出來的每一列資料, 會依序存在陣列的每一個元素裡面:
@x = `md5sum *.iso`;
但是上面的方法只適合用於資料量小, 或需要反複查詢的場合. 如果外部命令印出來的資料量太大, 全部讀入記憶體會很耗資源. 這時如果你的問題允許你循序每次只處理一列外部命令的輸出, 不需要經常回頭看過去的輸出, 那麼可以用第三種方法, 逐列處理:
open F, "find $ENV{HOME} -name '*.*htm*' |"; while (<F>) { ... } close F;
當然, 你也可以用內建模組 File::Find 做相同的事。
最後, 有時我們的 perl 程式所呼叫的外部命令是交談式的程式. 此時資料的流向顛倒過來, 變成是我們逐列送資料給外部程式. 還是用 open 的語法, 只不過 pipe 符號放的位置也顛倒過來:
open F, "| gnuplot"; print F "set term dumb\n"; print F "plot sin(x)\n"; close F;
- 本頁最新版網址: https://frdm.cyut.edu.tw/~ckhung/b/pl/communicate.php; 您所看到的版本: February 14 2012 10:32:25.
- 作者: 朝陽科技大學 資訊管理系 洪朝貴
- 寶貝你我的地球, 請 減少列印, 多用背面, 丟棄時做垃圾分類。
- 本文件以 Creative Commons Attribution-ShareAlike License 或以 Free Document License 方式公開授權大眾自由複製/修改/散佈。