Perl 程序管理

Perl 程序管理

Perl 中你可以以不同的方法來建立程序。

本教程將討論一些程序的管理方法。

  • 你可以使用特殊變數 $$$PROCESS_ID 來獲取程序 ID。

  • %ENV 雜湊存放了父程序,也就是shell中的環境變數,在Perl中可以修改這些變數。

  • exit() 通常用於退出子程序,主程序在子程序全部退出後再退出。

  • 所有開啟的控制代碼會在子程式中被 dup() 函式複製, 所有關閉程序所有控制代碼不會影響其他程序 。


反引號運算子

使用反引號運算子可以很容易的執行 Unix 命令。你可以在反引號中插入一些簡單的命令。命令執行後將返回結果:

#!/usr/bin/perl

@files = `ls -l`;

foreach $file (@files){
   print $file;
}

1;

執行以上程式,輸出結果如下:

drwxr-xr-x 3 root root 4096 Sep 14 06:46 9-14
drwxr-xr-x 4 root root 4096 Sep 13 07:54 android
-rw-r--r-- 1 root root  574 Sep 17 15:16 index.htm
drwxr-xr-x 3  544  401 4096 Jul  6 16:49 MIME-Lite-3.01
-rw-r--r-- 1 root root   71 Sep 17 15:16 test.pl
……

system() 函式

你也可以使用 system() 函式執行 Unix 命令, 執行該命令將直接輸出結果。預設情況下會送到目前Perl的STDOUT指向的地方,一般是螢幕。你也可以使用重定向運算子 > 輸出到指定檔案:

執行以上程式,輸出結果如下:

drwxr-xr-x 3 root root 4096 Sep 14 06:46 9-14
drwxr-xr-x 4 root root 4096 Sep 13 07:54 android
-rw-r--r-- 1 root root  574 Sep 17 15:16 index.htm
drwxr-xr-x 3  544  401 4096 Jul  6 16:49 MIME-Lite-3.01
-rw-r--r-- 1 root root   71 Sep 17 15:16 test.pl
……

你需要注意命令包含環境變數如 $PATH 或 $HOME 的輸出結果,如下所示:

例項

#!/usr/bin/perl $PATH = "我是 Perl 的變數"; system('echo $PATH'); # $PATH 作為 shell 環境變數 system("echo $PATH"); # $PATH 作為 Perl 的變數 system("echo \$PATH"); # 轉義 $ 1;

執行以上程式,輸出結果如下:

/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin
我是 Perl 的變數
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin

fork() 函式

Perl fork() 函式用於建立一個新程序。

在父程序中返回子程序的PID,在子程序中返回0。如果發生錯誤(比如,記憶體不足)返回undef,並將$!設為對應的錯誤資訊。

fork 可以和 exec 配合使用。exec 函式執行完引號中的命令後進程即結束。

例項

#!/usr/bin/perl if(!defined($pid = fork())) { # fork 發生錯誤返回 undef die "無法建立子程序: $!"; }elsif ($pid == 0) { print "通過子程序輸出\n"; exec("date") || die "無法輸出日期: $!"; } else { # 在父程序中 print "通過父程序輸出\n"; $ret = waitpid($pid, 0); print "完成的程序ID: $ret\n"; } 1;

執行以上程式,輸出結果如下:

通過父程序輸出
通過子程序輸出
2016年 6月19日 星期日 22時21分14秒 CST
完成的程序ID: 47117

如果程序退出時,會向父程序傳送一個CHLD的訊號後,就會變成僵死的程序,需要父程序使用wait和waitpid來終止。當然,也可以設定$SIG{CHLD}為IGNORG:

例項

#!/usr/bin/perl local $SIG{CHLD} = "IGNORE"; if(!defined($pid = fork())) { # fork 發生錯誤返回 undef die "無法建立子程序: $!"; }elsif ($pid == 0) { print "通過子程序輸出\n"; exec("date") || die "無法輸出日期: $!"; } else { # 在父程序中 print "通過父程序輸出\n"; $ret = waitpid($pid, 0); print "完成的程序ID: $ret\n"; } 1;

執行以上程式,輸出結果如下:

通過父程序輸出
通過子程序輸出
2016年 6月19日 星期日 22時30分56秒 CST
完成的程序ID: -1

Kill 函式

Perl kill('signal', (Process List))給一組程序傳送訊號。signal是傳送的數字訊號,9為殺掉程序。

首先看看linux中的常用訊號,見如下列表:

訊號名          值          標註          解釋
————————————————————————————————————————————————————————————
HUP             1           A             檢測到掛起
INT               2           A             來自鍵盤的中斷
QUIT            3           A             來自鍵盤的停止
ILL               4           A             非法指令
ABRT          6           C             失敗
FPE             8           C             浮點異常
KILL             9           AF            終端訊號
USR1          10          A             使用者定義的訊號1
SEGV          11          C             非法記憶體訪問
USR2          12          A             使用者定義的訊號2
PIPE           13          A             寫往沒有讀取者的管道
ALRM         14          A             來自鬧鐘的定時器訊號
TERM         15          A             終端訊號
CHLD          17          B             子程序終止
CONT         18          E             如果被停止則繼續
STOP         19          DF            停止程序
TSTP          20          D             tty鍵入的停止命令
TTIN            21          D             對後臺程序的tty輸入
TTOU          22          D             對後臺程序的tty輸出

以下例項向程序 104 和 102 傳送 SIGINT 訊號:

例項

#!/usr/bin/perl kill('INT', 104, 102); 1;