Perl - 程序管理



您可以使用 Perl 透過各種方式根據您的需求建立新程序。本教程將列出建立和管理 Perl 程序的一些重要且最常用的方法。

  • 您可以使用特殊變數$$$PROCESS_ID 獲取當前程序 ID。

  • 使用任何上述方法建立的每個程序都維護其自身的虛擬環境,位於%ENV 變數內。

  • 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
drwx------ 2 root root 4096 Sep 17 15:11 vAtrJdy

system() 函式

您還可以使用system() 函式執行任何 Unix 命令,其輸出將進入 perl 指令碼的輸出。預設情況下,它是螢幕,即 STDOUT,但您可以使用重定向運算子 > 將其重定向到任何檔案:

#!/usr/bin/perl

system( "ls -l")

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
drwx------ 2 root root 4096 Sep 17 15:11 vAtrJdy

如果您的命令包含 shell 環境變數(如 $PATH 或 $HOME),請小心。嘗試以下三種情況:

#!/usr/bin/perl

$PATH = "I am Perl Variable";

system('echo $PATH');  # Treats $PATH as shell variable
system("echo $PATH");  # Treats $PATH as Perl variable
system("echo \$PATH"); # Escaping $ works.

1;

執行上述程式碼時,將根據 shell 變數 $PATH 中設定的內容產生以下結果。

/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin
I am Perl Variable
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin

fork() 函式

Perl 提供了一個fork() 函式,它對應於同名的 Unix 系統呼叫。在大多數可使用 fork() 系統呼叫的類 Unix 平臺上,Perl 的 fork() 只會呼叫它。在某些平臺(如 Windows)上,fork() 系統呼叫不可用,Perl 可以在直譯器級別模擬 fork()。

fork() 函式用於克隆當前程序。此呼叫建立一個新的程序,執行相同的程式,並在同一點執行。它將子程序 pid 返回給父程序,將 0 返回給子程序,或者如果 fork 不成功則返回 undef。

您可以在程序中使用exec() 函式啟動請求的可執行檔案,該可執行檔案將在單獨的程序區域中執行,並且 exec() 將等待它完成,然後以與該程序相同的退出狀態退出。

#!/usr/bin/perl

if(!defined($pid = fork())) {
   # fork returned undef, so unsuccessful
   die "Cannot fork a child: $!";
} elsif ($pid == 0) {
   print "Printed by child process\n";
   exec("date") || die "can't exec date: $!";
  
} else {
   # fork returned 0 nor undef
   # so this branch is parent
   print "Printed by parent process\n";
   $ret = waitpid($pid, 0);
   print "Completed process id: $ret\n";

}

1;

執行上述程式碼時,將產生以下結果:

Printed by parent process
Printed by child process
Tue Sep 17 15:41:08 CDT 2013
Completed process id: 17777

wait()waitpid() 可以作為 fork() 返回的偽程序 ID 傳遞。這些呼叫將正確等待偽程序的終止並返回其狀態。如果您使用 fork() 而從未使用 waitpid() 函式等待您的子程序,則會累積殭屍程序。在 Unix 系統上,您可以透過將 $SIG{CHLD} 設定為“IGNORE”來避免這種情況,如下所示:

#!/usr/bin/perl

local $SIG{CHLD} = "IGNORE";
 
if(!defined($pid = fork())) {
   # fork returned undef, so unsuccessful
   die "Cannot fork a child: $!";
} elsif ($pid == 0) {
   print "Printed by child process\n";
   exec("date") || die "can't exec date: $!";
  
} else {
   # fork returned 0 nor undef
   # so this branch is parent
   print "Printed by parent process\n";
   $ret = waitpid($pid, 0);
   print "Completed process id: $ret\n";

}

1;

執行上述程式碼時,將產生以下結果:

Printed by parent process
Printed by child process
Tue Sep 17 15:44:07 CDT 2013
Completed process id: -1

kill() 函式

Perl kill('KILL', (程序列表)) 函式可用於透過向其傳遞 fork() 返回的 ID 來終止偽程序。

請注意,在偽程序上使用 kill('KILL', (程序列表)) 通常會導致記憶體洩漏,因為實現偽程序的執行緒沒有機會清理其資源。

您可以使用kill() 函式向目標程序傳送任何其他訊號,例如,以下操作將向程序 ID 104 和 102 傳送 SIGINT:

#!/usr/bin/perl

kill('INT', 104, 102);
 
1;
廣告