天天看點

Perl語言入門——程序管理

system函數:在perl中,啟動子程序最簡單就是system函數,例如調用Unix的date指令,隻需system "date";

    提供給system函數的參數就是那些在shell中常常鍵入的指令,對與比較複雜的指令,隻需把它全部放進參數裡就行,如

    system 'ls -l $HOME'; (用單引号為了避免内插變量)

    子程序運作時,perl會等待他結束,再繼續運作,不過可以利用shell功能來啟動背景程序

    system "long_running_command with paramenters &";

    由于指令行結尾的&号,shell讓long_running_command成為背景程序并立即退出,這樣perl注意到

    shell已經傳回了,就可以做别的事情了

避免使用shell:system函數也可以用一個以上的參數調用,這樣不管文本多複雜,都不會用到shell

    my $tarfile="something*wicked.tar";

    my @dirs=qw(fred|flintstone <arney&rubble> betty);

    system "tar","cvf",$tarfile,@dirs;

exec函數:system函數的所有文法都适用于exec函數,一個重要例外就是system函數會建立子程序在perl睡眠期間執行任務,而exec函數卻導緻perl程序自己去執行任務

環境變量:在perl中,環境變量對應于特殊的%ENV哈希,其中每一個鍵都代表一個環境變量。

    在程式開始運作時,%ENV會保留從父程序(通常為shell)繼承來的設定值,修改此哈希就能改變環境變量,也能被perl調用的子程序繼承。

    下面例子調用系統的make程式,并以私有目錄作為尋找指令的首選位置,還禁用IFS環境變量

    $ENV{'PATH'}="/home/rootbeer/bin:$ENV{'PATH'}";

    delete $ENV{'IFS'};

    my $make_result= system "make";

用反引号捕獲輸出結果:無論是system還是exec調用,都會定向到perl的标準輸出,若要捕獲輸出的字元串

    并進一步處理,隻要以魔力反引号``來代替單引号或雙引号。

    my $now= `date`;  #捕獲date的輸出;

    print "The time is now $now"; #這裡不需要換行符,date輸出裡已包含

    若要取得與Unix shell一樣去除最後一個換行符的效果,隻需用chomp

    perl解釋反引号裡的值的方式類似于system的單參數形式,并且在解釋器中會以雙引号

    字元串形式展開,這意味着反斜線轉義與變量内插都會正常處理

    下面取得一系列perl函數的說明文檔

    my @function=qw{int rand sleep length hex eof not exit sqrt umask};

    my �out;

    foreach (@function){

        $about{$_}=`perldoc -t -f $_`;

    }

在清單上下文中使用反引号:如果指令會輸出很多行,在标量上下文中使用反引号會得到一個很長的文本串

    而在清單上下文中則傳回輸出的文本行清單

    假如who指令會用多行列出目前登入系統的每個使用者

    my $who_lines=`who`;可以得到多個拆分好的以換行符結尾的字元串,調用chomp

    可以删除所有元素結尾的換行符。

    foreach(`who`){

        my($user,$tty,$date)=/(\S+)\s+(\S+)\s+(.*)/;

        $ttys{$user}.="$tty at $date\n":

    }

    正規表達式用于得到不同的資訊

将程序視為檔案句柄:之前的方法都是perl同步控制子程序,啟動一個指令,等它結束,或者擷取輸出

    perl也可以啟動一個異步運作的子程序,并和它保持通信直到子程序結束執行

    要啟動并發的子程序,将指令放在open調用的檔案名部分,并在它前面或後面加上豎線

    open DATE, "date|" or die "can not pipe from date:$!";

    open MAIL, "|mail merlyn" or die "can not pipe to mail:$!";

    豎線在指令右邊,表示該指令執行時它的标準輸出會轉向隻讀的檔案句柄DATE

    豎線在左邊,指令的标準輸入會連接配接到隻寫檔案句柄MAIL

    對于以讀取模式打開的檔案句柄,隻需這樣讀 my $now=<DATE>;

    想傳遞資料給mail程序,隻要列印到檔案句柄 print MAIL "The time is now $now";

    下面用find指令查找那些90天内未被存取過的1000塊以上的大檔案

    open F,"find / -atime +90 -size +1000 -print|" or die "fork:$!";

    while(<F>){

        chomp;

        printf "%s size %dK last accessed on %s\n",

        $_,(1023 + -s $_)/1024,-A $_;

    }

    在find工作時,perl會等待,每找到一個檔案,perl會立刻收到檔案名并進一步顯示檔案的相關資訊供分析,如果我們用反引号調用它的話,就是等到find徹底搜完才能看到一行輸出

發送及接收信号:通常某個重大事件發生時就會發出信号,例如在終端上按下Control-C這樣的中斷組合鍵,就會給與此終端相連的所有程序發送SIGINT信号

    例如發送SIGINT信号給程序4201,如下

    kill 2,4201 or die "Cannot dignal 4201 with SIGINT:$!";

    發送信号的指令取名為kill,2号信号就是SIGINT,也可以改成字元串INT。如果該程序早已退出就會收到傳回的錯誤,可以用此判斷程序是否存活.

    編号為0的特殊信号用來測試能否發送信号,如下

    unless (kill 0, $pid){ warn "$pid has gone away !";}