Perl的學習筆記
1:使用背景。
客戶的機器是qnx系統,一個不常見的操作系統,還是一個v4.25的,版本很低。并且,幾乎不能停機,也不能安裝什么額外的東西。所以選用perl。還是底版本的perl5.002。
qnx是個實時操作系統,unix系列的一種,優秀的適合嵌入式應用的操作系統。新版本還有試用版,低版本的就只有商業版了。
2:學習環境:
我先使用的是Ubuntu操作系統來模擬Qnx系統。然后下載了一個最新版的perl來學習。最新版本perl5.8.8.x。運行環境:ActivePerl;開發環境 Dzsoft Perl Editor。Ubuntu是最近比較流行的linux系統。Perl環境也是5.8.8.x
ActivePerl:一個運行環境。提供了大量函數(類庫)。有win版的,也有linux版本的。我從網上能找到5.005版的,for perl。
Dzsoft Perl Editor:一個開發工具。可以調試,編輯,運行代碼。簡潔,實用。
3:語言特點
perl是一種自由且功能強大的編程語言。它被用作 Web 編程、數據庫處理、XML 處理以及系統管理等等。可以用在絕大多數的unix系統之上。可以最底層的和nuix系統交互。
Perl生于1987,v5之后就穩定成熟起來。Perl是"實用的摘要 和報告語言"的縮寫字。感覺他非常底層。寫最基本的輸出語句(如果是web應用的話,和php非常相似);如果用來操作文件等,就非常和unix系統接近了(最初的目標也就是這里把);至于報表,沒有用過,不知道怎么樣。就像.net,他也有一個比較大的支持庫。Active Perl就提供了不少。其他的網上也有的下。需要簡單安裝。我這次就下載了一個操作ini文件的類庫:Config::IniFiles;
4:變量、基本語法
幾年前用過php,感覺perl的變量、語法和他真相(或者說是php學的它)。
變量符號分幾種:
$ 字符串:比如$a=”tt”; $_表示默認參數
@ 數組:$a=@[0]. @_表示默認參數。
變量范圍
$xx什么都不寫,表示全局變量。整個文件中都可以訪問到;
local $xx 表示局部變量,但是這個值可以被其調用的子程序訪問到
my $xx 表示局部變量,只能在這一個函數里面可以使用,子程序就不能使用
數據類型
都存在一個單元里,可以自由變換。
$len=@a;就成了取得長度;$a+$b;$a*$b都可以。
這個特點很像php
函數定義
{
local ($a,$b)=@_;
return “”;
}
注意: 函數后便沒有(),也沒有參數列表定義。也就是說,他接受任何形式的參數,以數組的方式傳遞過來。所以內部使用的話,就用@_這個默認當前參數來取之。
對了,perl里面語句也是用“;”來分開的。注釋使用“#”。
操控語句(語法)
for, if , while 這幾個都是php/c/c#這個系列類似的。也有特殊或者說是很靈活的用法,比如do untill, do xxx if(statement);等。俺膽小,沒敢用這么多語法在里面。
5:實用技巧
取得命令行輸入的參數
比方說,這樣的啟動運行命令 “perl.exe main.pl 1”。
異常處理
沒有提供基礎的try catch。有這樣一個類似作用的語句可以實現類似的功能:
{
StatusReport();
};
if($@)#ftp error . here is like try catch
{
Log("App Error [StatusReport]. [$@]",$appLog);
}
網上也由提供的類庫,實現try catch. 不過,我覺得eval就已經挺好用了。
至于拋出異常,用die()
調用外部類庫(安裝/部署)
這個需要放在文件頭上
use Net::FTP;
至于該文件,就放在lib目錄下的相應位置。比Config::IniFiles放在../lib/Config/IniFiles.pm
類(模塊)的使用
就拿上一個Config::IniFiles做例子。
這個實例化的方法看著還眼熟,其它也有好幾個方法,不過看著別扭。
Timer
基本的用法里面,沒有timer,雖然又提供的幾個類,但還是用著很不爽。所以,到了最后,基本上就是使用while循環來代替了。While循環+sleep()函數來簡單實現,用著還過得去。
文件/目錄 操作
打開文件 :open(FH, "$flagFile") or die "Couldn't open $flagFile for reading: $!"; 注意,用完了就要關閉它。 Close FH; 寫文件 :print FH $flag; 讀文件 :@reads=<FH>; return @reads[0]; 拷貝文件:copy(xx,xx);刪除文件:unlink();創建文件:open(FH, "> $flagFile") 追加寫打開。
獲得文件大小:-s 。 $size=-s $file; 獲得文件時間:$mtime=(stat("$pathFrom/$fileName" ));
打開目錄:opendir(DIR,$pathFrom); 注意,也要closedir它;讀取目錄:
for(@dots)
{$fileName=$_;#取得默認值}
創建目錄:mkdir("$failedPath/$taskName",0777);
刪除目錄:rmdir($dir)
判斷是否是目錄:if(!-d "$appPath/Log/$taskName")
日期 操作
{
local @A =@_; #YYYYDDMMHHMMSS
return sprintf("%04s%02s%02s%02s%02s%02s",$A[5]+1900,$A[4]+1,$A[3],$A[2],$A[1],$A[0]);
}
sub DiffDaysFromNow #span of days
{
local @A =@_;
local @now=localtime(time());
return (@now[5]- $A[5])*360+($now[4]-$A[4])*30+(@now[3]-$A[3]);
}
時間格式取得的是unix格式的。所以要做一些轉化:LocalTime($time)。比方說,取得文件時間:
my $fileDate= DateFormat( localtime($mtime) ) ;
取得當前時間: local @now=localtime(time()); 另外一種時間就是格林威治時間。看起來沒什么用,對我來說。
字符串操作
定義:使用””。 比如:$a=”ttt”;。 如果是單引號,有其他的意思,好像是執行外部命令
比較:eq ==
連接:. 比方說 $a.Sb 。就相當于兩個字符串連接了。也可以以這樣$c=”$a$b”。一樣可以解釋出來。
Substr:substr($ftpURL,index($ftpURL,"@",0)+1)
Split:my @list=split(",",$config);
格式輸出 :sprint f("%04s%02s%02s%02s%02s%02s",$A[5]+1900,$A[4]+1,$A[3],$A[2],$A[1],$A[0]);
數學計算:+-*/。
多線程:網上有提供的一個庫。不是很穩定(安全)。
6:遺留問題
文件目錄處理(遞歸處理),因為取得目錄需要定義一個dir句柄(opendir DIR),怎么在遞歸的程序里面重新定義一個新的dir變量呢?因為他們總是重名。
執行外部命令并獲得輸出結果,有幾種方式:system(‘cmd’); exec(‘cmd’); $cmd=’cmd’;但是每一種方式之后,界面上都有了輸出結果,而我如何得到這個輸出結果呢?重訂向到一個文件?我嘗試了這樣的方法 $cmd=’cmd’; if($cmd==“”)…..。 $cmd里面好像總是”cmd”字符串,沒有執行的結果。