Perl 是 1990 年代網際網路的「膠水語言」:第一代動態網站的 CGI 程式、伺服器上的日誌分析與系統管理腳本,大多是 Perl 寫的。它的正則表達式能力至今仍是各語言的標竿,但在網頁開發領域,它的位置已被 PHP、Python 等語言接手。這篇文章整理 Perl 的基本語法(變數、流程、子程式、正則表達式、檔案處理),說明它現在還用在哪裡、舊網站的 cgi-bin 裡遇到 Perl 該怎麼辦。本文屬於《網頁程式語言》系列,總覽見〈網頁程式設計是什麼〉。
一、Perl 是什麼?
Perl 是 Larry Wall 於 1987 年發布的通用直譯式程式語言,名稱常被解釋為 Practical Extraction and Report Language,設計目標是讓文字處理與系統管理工作寫起來又快又短。它吸收了 C、shell、sed 與 awk 的特性,語法自由度極高,同一件事有很多種寫法,Perl 社群稱之為「There is more than one way to do it」。
Perl 在網頁史上的位置很明確:1990 年代中期到 2000 年代初,動態網頁幾乎等於「Apache 加 cgi-bin 裡的 Perl 程式」,留言板、計數器、表單寄信程式都是 Perl 寫的。它的模組庫 CPAN 至今仍是最大、最老的程式套件庫之一。
二、Perl 基本語法
Perl 的敘述以分號結尾、區塊用大括號,變數依類型用 $、@、% 三種符號開頭。以下範例在任何 Linux 或 macOS 都能直接執行,Windows 需另外安裝 Strawberry Perl。
1. Hello, World 與 strict、warnings
#!/usr/bin/perl use strict; use warnings; use utf8; binmode(STDOUT, ":encoding(UTF-8)"); print "Hello, World!\n";
前兩行 use strict 與 use warnings 幾乎是所有 Perl 程式的固定開頭:前者強迫變數先宣告,後者對可疑寫法發出警告;沒有它們的舊程式,錯誤會靜靜地被吞掉。處理中文時再加上 use utf8 與輸出編碼設定。
2. 三種變數:標量、陣列、雜湊
my $name = "王小明"; # 標量 $:單一值
my $age = 30;
my @colors = ("紅", "綠", "藍"); # 陣列 @:有序清單
my %person = (name => "王小明", age => 30); # 雜湊 %:鍵值對
print "姓名:$name,年齡:$age\n";
print "第一個顏色:$colors[0],共 ", scalar(@colors), " 個\n";
print "雜湊取值:$person{name}\n";
初學者最容易混淆的是符號會隨用法改變:整個陣列是 @colors,但取其中一個元素是 $colors[0],因為取出來的是單一值。
3. 條件判斷
my $age = 18;
if ($age >= 18) {
print "您已成年\n";
} elsif ($age >= 12) {
print "您是青少年\n";
} else {
print "您是兒童\n";
}
print "可以投票\n" if $age >= 18; # 後置條件,Perl 特有的簡寫
print "未成年\n" unless $age >= 18; # unless = if not
字串比較要用 eq、ne,數字比較才用 ==、!=,兩者混用是 Perl 最常見的錯誤來源。
4. 迴圈
for my $i (1..5) {
print "這是第 $i 次迴圈\n";
}
my @colors = ("紅", "綠", "藍");
foreach my $color (@colors) {
print "$color\n";
}
my $j = 1;
while ($j <= 3) {
print "while 第 $j 次\n";
$j++;
}
5. 子程式
sub say_hello {
my ($name, $greeting) = @_; # 參數都放在 @_ 陣列
$greeting //= "Hello"; # 沒給就用預設值
return "$greeting, $name!";
}
print say_hello("Alice"), "\n";
print say_hello("Bob", "您好"), "\n";
Perl 5 的子程式沒有正式的參數列(5.36 起可用 use feature 'signatures' 開啟),傳統寫法是從 @_ 取出參數,這是閱讀舊程式時一定會看到的模式。
6. 正則表達式
正則表達式是 Perl 的招牌,其他語言的「PCRE」(Perl 相容正則表達式)名稱就來自它。
my $text = "訂單編號 A12345 於 2024-05-01 成立";
if ($text =~ /([A-Z]\d{5})/) { # =~ 表示比對;括號捕捉
print "找到編號:$1\n";
}
(my $masked = $text) =~ s/\d{4}-\d{2}-\d{2}/****-**-**/; # s/// 替換
print "$masked\n";
my @numbers = ($text =~ /\d+/g); # g 旗標:取出所有數字
print "共 ", scalar(@numbers), " 組數字\n";
從日誌檔抓出所有 IP、把報表裡的日期統一格式、驗證 Email 格式,這類工作 Perl 一行就能完成,這也是它在系統管理領域長壽的原因。
7. 檔案處理
open(my $in, '<:encoding(UTF-8)', 'access.log') or die "無法開啟檔案:$!";
my %count;
while (my $line = <$in>) {
my ($ip) = $line =~ /^(\d+\.\d+\.\d+\.\d+)/;
$count{$ip}++ if $ip;
}
close($in);
open(my $out, '>:encoding(UTF-8)', 'report.txt') or die "無法寫入檔案:$!";
foreach my $ip (sort { $count{$b} <=> $count{$a} } keys %count) {
print $out "$ip\t$count{$ip}\n";
}
close($out);
這段程式讀取網站存取日誌、統計每個 IP 出現次數並由高到低寫成報表,是 Perl 最典型的用途;同樣的需求,我們在檢查 AI 爬蟲造訪紀錄時也是用這種方式處理伺服器 log。
三、Perl 與 CGI:第一代動態網頁
Perl 之所以和網頁扯上關係,是因為 CGI:網頁伺服器把每一次請求交給外部程式執行,而當年最順手的外部程式語言就是 Perl。典型的 Perl CGI 程式讀取表單、印出 Content-Type 標頭、再輸出 HTML。這種每次請求都啟動一個程序的模式效能很差,後來被 mod_perl、FastCGI 以及 PHP 這類內建於伺服器的方案取代。CGI 的運作原理、範例與現況,統一寫在〈CGI 是什麼〉,本文不重複。
四、Perl 的現況:還有人用嗎?
有,但幾乎不在網頁開發:Perl 5 仍持續發版,用途集中在系統管理、文字與日誌處理、生物資訊,以及維護既有系統。
- 語言仍在維護:Perl 5 每年推出新版(5.40、5.42 等),CPAN 持續更新;原本規劃的 Perl 7 大改版在 2020 年宣布後轉為漸進式演進,目前沒有明確時程。
- Linux 主機幾乎都內建 Perl:很多系統工具本身就是 Perl 寫的,所以它不會消失,但這不代表適合拿來寫新網站。
- 網頁框架存在但小眾:Mojolicious、Dancer、Catalyst 都能做現代網站,只是社群與人才規模遠不及 PHP、Python 生態。
- 新手該學嗎:以網頁開發為目標的人不需要,把時間投在 PHP 或 Python 更划算;系統管理與資料清理工作者則值得學它的正則表達式與單行指令。
五、舊網站的 cgi-bin 裡有 Perl 怎麼辦?
網站改版前的技術盤點,只要在主機看到 cgi-bin 目錄與 .pl、.cgi 檔,我們會依三個問題決定處置:
- 它還在被用嗎?看存取日誌有沒有請求打到這些程式。留言板、計數器這類功能多半早已停用,可以直接下線並對舊網址做 301 或 410。
- 它做的事現在怎麼做?表單寄信、簡易查詢等功能,改用 PHP 或現有系統的模組重做通常更快;不要試圖把 Perl CGI 搬到新主機,新主機常沒有 CGI 環境或缺少所需的 CPAN 模組。
- 有沒有資安風險?二十年前的 CGI 程式普遍沒有輸入驗證,是被植入垃圾內容或寄送垃圾信的常見破口。無法確認安全的程式,寧可先停用。
本站(newscan.com.tw)以 PHP 建置,沒有 Perl CGI;上述做法來自替客戶盤點舊站的實務,不涉及特定客戶資料。
六、結論
Perl 是一門仍在維護、擅長文字處理與系統管理的語言,它在網頁開發的歷史角色已經結束,但留在無數舊主機的 cgi-bin 裡。學它的價值在正則表達式與看懂舊程式;做新網站請選擇主流的伺服器端語言,各語言的比較見〈網頁程式設計是什麼〉。
七、常見問答 FAQ
Perl 是什麼?
Perl 現在還有人用嗎?
Perl 和 Python 哪個好?
cgi-bin 裡的 .pl 檔是什麼?可以刪嗎?
Perl 的正則表達式為什麼有名?
參考來源
- Perl,〈Perl documentation(perldoc)〉,Perl 官方文件。
- Perl,〈perlre:Perl regular expressions〉,Perl 官方文件。
- Perl Steering Council,〈What happened to Perl 7?〉,Perl 官方部落格,2022。
- MetaCPAN,〈Comprehensive Perl Archive Network〉,CPAN 模組庫。
- 新視野網頁設計,〈CGI 是什麼?運作原理、Perl 與 Python 範例、現況與替代方案〉,本站自有內容。
Perl 版本與 Perl 7 進度依撰寫時查閱的 Perl 官方文件與部落格整理;第五節為本站盤點舊網站時的實務原則,不涉及特定客戶資料。