發新話題

網路管理語言 Perl 入門與實作

23. 連接MySQL
本章介紹 Perl 搭配 MySQL 的方法

Perl 要搭配資料庫,必須安裝以下模組:
引用:
1. DBI : Perl 的 DataBase Interface 的簡稱,

請至

ftp2.tnc.edu.tw/pub/unix/perl/CPAN/modules/by-module/DBI

抓取:DBI-1.37.tar.gz

tar xvzf DBI-1.37.tar.gz

cd DBI-1.37

perl Makefile.PL
make
make test
make install

2. Data-ShowTable

請至

ftp2.tnc.edu.tw/pub/unix/perl/CPAN/modules/by-module/Data

抓取:Data-ShowTable-3.3.tar.gz

安裝方法同 DBI。

3. DBD::資料庫driver

因為我想和 MySQL 搭配,所以必須安裝 DBD::mysql 的驅動程式

請至

ftp2.tnc.edu.tw/pub/unix/perl/CPAN/modules/by-module/DBD

抓取:Msql-Mysql-modules-1.2219.tar.gz 或 DBD-mysql*.tar.gz

安裝方法同 DBI。
至此,Perl 即可和 MySQL 一起運作了! 注意:通常,若您使用的是套件版的 Perl/MySQL,通常系統中已有相關的 DBI/DBD 了,比如:perl-DBI-1.32*.rpm (即 DBI)/ perl-Mysql-1.22_19*.rpm(即 DBD::mysql),因此,您不一定要安裝上面這些 tarbll 模組。
引用:
#! /usr/bin/perl

use DBI;
use strict;

my $db="test";
my $host='localhost';
my $user='root';
my $password='ppp123';

my $dbh = DBI->connect("DBI:mysql:database=$db;host=$host",
                     $user, $password, {RaiseError => 1});

open(FHD, "stu.csv") or die;
while (my $line=<FHD>) {
        chomp($line);
    my ($f1, $f2, $f3, $f4, $f5)=split(/\,/,$line);
    if ($f1) {
        my $q=qq[ INSERT INTO stu_table VALUES ("$f1", "$f2", "$f3", "$f4", "$f5") ];
            my $sth=$dbh->prepare($q);
            unless($sth->execute) {die "$!\n";}
    }
}
close(FHD);
實例:
引用:
我在 test 這個資料庫中開了一個 table 叫 aaa,其結構如下:

CREATE TABLE `aaa` (
  `no` varchar(10) NOT NULL default '',
  `name` varchar(12) NOT NULL default ''
)

其中 no 代表身份證字號,name 代表姓名。

我準備用它來儲存 studdemo.csv 中的學生身份證及姓名!

程式如下:

#! /usr/bin/perl

use DBI;
use strict;

my $db="test";
my $host='localhost';
my $user='root';
my $password='1234';

my $dbh = DBI->connect("DBI:mysql:database=$db;host=$host",
                     $user, $password, {RaiseError => 1});

open(FHD, "stu.csv") or die;
while (my $line=<FHD>) {
        chomp($line);
    my ($f1, $name, $f3, $f4, $f5, $f6, $f7, $pslno, $f9)=split(/\,/,$line);
    if ($f1) {
        my $q=qq[ INSERT INTO aaa VALUES ("$pslno", "$name") ];
            my $sth=$dbh->prepare($q);
            unless($sth->execute) {die "$!\n";}
    }
}
close(FHD);

TOP

24. 樂彩號碼產生器
僅供練習用。中不中與我無干!

loto66.pl
引用:
#! /usr/bin/perl
use strict;

our @tg;

# set num scope
my $max_num = 42;
my $spe_num;
my $gen_num=6;

# init key
my $init_key;

srand( time() ^ ($$ + ($$ << 15)) );

# ask question
print "請問您要產生幾組號碼呢 ?\n";
my $set_num=<>;
chomp $set_num;


if ($set_num <= 0) { $set_num = 1; }

# gen num
my $i;
for ($i=1; $i<=$set_num; $i++) {
      my $a=gen_loto6($gen_num);
      p_loto($a);
}

# p_tg();

sub gen_loto6 {
    my $n = shift;
    my $i; my $j;
    my @temp;
    my $r=0;
    for ($i=0; $i < $n; $i++) {
        $temp[$i] = (1..42)[42 * rand];
        for ($j=0; $j<$i; $j++) {
            if ($temp[$i]==$temp[$j]) {
                $i--; last;
            }
        }
        my $t=$temp[$i];
        $tg[$t]++;
    }
    return \@temp;
}


sub p_loto {
    my $r = shift;
    my @a = @$r;
    my $i;
    my @list66;
    for ($i=0; $i<=$#a; $i++) {
        if (length($a[$i])==1) {
            push @list66, "0$a[$i] ";
        } else {
            push @list66, "$a[$i] ";
            
        }
    }
    @list66 = sort @list66;
    print "@list66\n";
}

sub p_tg {
    for ($i=1; $i<=42; $i++) {
        print "$i ===> $tg[$i]\n";
    }
}

TOP

25. 物件導向
本章介紹 Perl 5 的物件導向技術

待續 ......

TOP

26. 網路程式設計
本章介紹 Perl 網路程式設計。

26.1 偵測主機存活
這一節我們要來寫一支簡單的網路程式,用來偵測您所管理的主機是否存活。

程式分成二部份:



偵測程式

觀看程式,以 CGI 程式來呈現。


首先是偵測程式,這支程式需用到 Net:ing 這個模組。

先來看一下,系統中是否已安裝 Net:ing? 檢查的方法如下:
引用:
#! /usr/bin/perl

use Net:ing;


以上存成 ping.pl,chmod +x ping.pl,執行 ./ping.pl

若沒有出現任何錯誤訊息,則表示該模組已經有安裝了,否則,表示沒有安裝。
若出現錯誤訊息,則要先來裝一下 Net::Ping,安裝方法如下:
引用:
perl -MCPAN -e shell

cpan>install Net::Ping


請參考第 10 章模組的安裝說明。

TOP

26.2 偵測程式
接著,我們利用 Net:ing 來寫一支簡單的偵測程式,如下:
引用:
#! /usr/bin/perl

use Net:ing;
use strict;

# 網站主要目錄的路徑,請修改成您的現況
my $prefix="/home/apache/htdocs";

# 記錄檔路徑
my $ping_log = "$prefix/ping.log";
open(FHD, "> $ping_log") || die "$!\n";

my $p = Net:ing->new('icmp');

# 欲偵測的主機 IP 列表,這裡只是舉例,請把它改成您管理的主機 IP
my @HOST=qw(
        10.1.1.1
        10.1.1.2
        10.1.1.3
        10.1.1.4
        10.1.1.222
);

my $i;
for ($i=0; $i<=$#HOST; $i++) {

        # 只 ping 一秒鐘,超過一秒鐘沒有反應,即視為斷訊
        # 若連通則 $result 值為 1,若斷訊 $result 值為 0
        my $result=$p->ping($HOST[$i], 1);

        # 取得時間
        my $now=get_time();

        # 寫入記錄檔 ping.log 中
        print FHD "$HOST[$i],$result,$now\n";
}

close(FHD);


# 取得時間的副程式
sub get_time {

        # 取得秒, 分, 時, 日, 月, 年
        my ($sec,$min,$hour,$day,$mon,$year)=localtime(time);

        # 月比實際少一, 所以加 1
        $mon++;

        # 判斷是否為個位數, 若是則在前面補 0
        if (length ($mon) == 1) {$mon = '0'.$mon;}
        if (length ($day) == 1) {$day = '0'.$day;}
        if (length ($hour) == 1) {$hour = '0'.$hour;}
        if (length ($min) == 1) {$min = '0'.$min;}
        if (length ($sec) == 1) {$sec = '0'.$sec;}

        # 年比實際西元年少 1900, 所以加上 1900
        $year+=1900;

        # 組合成完整的時間
        my $alltime="$year/$mon/$day $hourminsec";
使用法:(需要 root 權限才能執行)
引用:
1. 將上述程式存成 ping.pl,放入 /root 中

2. 給執行權:

        chmod +x ping.pl

3. 放入 crontab 中,每 5 分鐘定時執行一次:

        crontab -u root -e

        */5 * * * * /root/ping.pl

TOP

26.3 觀看程式
寫一支簡易的 CGI 程式,以觀看偵測的結果,如下:
引用:
#! /usr/bin/perl

print "Content-type: text/html\n\n";

print <<HERE;
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=big5">
<title>管理主機存活列表</title>
</head>
<body bgcolor="white">
<table border=2 align=center>
<tr><td colspan=3 align=center><H1>管理主機存活列表</H1></td></tr>
<tr><td align=center>主機</td><td align=center>連線狀況</td><td align=center>偵測時間</td></tr></tr>
HERE

# 網站主要目錄的路徑,請修改成您的現況
my $prefix="/home/apache/htdocs";

# 記錄檔路徑
my $ping_log = "$prefix/ping.log";
open(FHD, "$ping_log") || die "$!\n";

while(<FHD>) {
        chomp;
        my ($host, $alive_or_not, $time)=split(/,/);
        my $status=($alive_or_not) ? "<font color=blue>連 通</font>" : "<font color=red>斷 訊</font>";
        print "<tr><td>$host</td><td align=center>$status</td><td align=center>$time</td></tr>\n";
}

close(FHD);

print <<HERE2;
</table>
</body>
</html>

HERE2
使用法:
引用:
1. 將上述程式存成 viewping.cgi,放入 Web 的 cgi-bin 目錄中

2. 給執行權:

        chmod +x viewping.cgi

3. 在瀏覽器中執行:

        http://您的主機/cgi-bin/viewping.cgi
以下是執行結果:

Figure 1. 主機存活列表

TOP

26.4 簡易郵寄程式
我們可以利用 Perl 的檔案處理功能(打開管線),製作一支簡易的郵寄程式,這支程式會透過 Mail Server 來幫我們送信。程式如下:
引用:
#! /usr/bin/perl

print "請輸入收信人位址? ";
chomp($theman=<STDIN>);

mail_to($theman);

# 郵寄副程式
sub mail_to {

        $to=shift || "defaultman\@yourdomain.is";

        # sendmail 程式路徑位址
    my $mailprg = "/usr/sbin/sendmail -t";

        # 寄件者 Email
    my $from = "pizapiza\@mydomain.is";

    open (MAIL,"|$mailprg") || die "$!\n";
    print MAIL "Return-Path: $from\n";
    print MAIL "From: $from\n";
    print MAIL "To: $to\n";
    print MAIL "Subject: 簡易郵寄程式測試\n";
    print MAIL "\n";
    print MAIL "Hi! 您好! 這是一封郵件測試!!!\n\n";
    print MAIL "--- mail test for u (c) 2003 written by OLS3\n";
    close(MAIL);

        print "OK!\n\n";
}
使用法:
引用:
1. 上式存成 mailto.pl

2. chmod +x mailto.pl

3. ./mailto.pl
註1:您的 Sendmail 或 Postfix Server 必須啟動才行。

註2:這支程式略作修改,由檔案或資料庫中取得使用者郵件列表,即可製成大量送信程式。

TOP

26.5 通訊端點:Socket
Perl 支援 Socket,功能非常強大,拿來寫網路 client 端程式,甚至寫 Server,都非常簡便,效能也很好喲!

那麼,Socket 是什麼呢?

Socket 是一個網路通訊的端點,它是與外界網路連通的一個介面。Socket 其實和檔案代碼(File Handle)很像,只要針對這個介面做讀寫動作,便可完成遠端通訊的工作。

這裡我們要介紹 IO::Socket 這個模組的簡單用法。

TOP

26.6 抓網頁程式
以下這支程式很像 wget,可用來抓取指定的網頁檔案。
引用:
#! /usr/bin/perl

use strict;

# 使用 IO::Socket 模組
use IO::Socket;

# 取得命令列中的網頁位址,放入 $url 中
my $url=shift || die "您沒有輸入 url 網址!\n";

# 比對網頁位址是否合乎格式?
my ($host, $file) = $url =~ m!訪客無法瀏覽此圖片或連結,請先 註冊登入會員 [^/]+)(/[^\#]*)!;  #(註1)

# 若比對正確,才抓取
if ($host) {

        # 產生一個 IO::Socket::INET 物件
        my $socket = IO::Socket::INET->new(
                PeerAddr => $host,                        # 指定主機位址
                PeerPort => 'http(80)'                # 指定 port 號
        );

        # 針對 $socket 寫入,此動作形同對 $host 主機提出網頁檔 $file 的要求
        print $socket "GET $file HTTP/1.0\n\n";

        # 只要由 $socket 讀到一列資料,就處理之
        while(my $line=<$socket>) {

                # 把 CR (^M) 換掉
                $line =~ s/\r//g;

                # 顯示該列內容 (註2)
                print $line;

        }

}
使用法:
引用:
1. 存成 wget.pl

2. chmod +x wget.pl

3. ./wget.pl 訪客無法瀏覽此圖片或連結,請先 註冊登入會員 > FSF.htm
註1:取自 Network Programming with Perl, 119 頁. Lincoln D.Stein. Addison Wesley. 2001

註2:本程式連 Web server 送給 client 端的表頭訊息,都會顯示出來。比如:
引用:
HTTP/1.1 200 OK
Date: Thu, 2 Aug 2003 23:55:46 GMT
Server: Apache/1.3.26 (Unix) PHP/4.1.2
Last-Modified: Tue, 2 Apr 2002 06:13:58 GMT
ETag: "9d821-5dac-3cc4fba6"
Accept-Ranges: bytes
Content-Length: 23980
Connection: close
Content-Type: text/html
註3:這裡有 IO::Socket::INET 的 訪客無法瀏覽此圖片或連結,請先 註冊登入會員 ,可執行 perldoc IO::Socket::INET 取得。

TOP

27. 轉換 DOS/UNIX 檔案案格式
本章介紹如何將 DOS 格式的檔案和 UNIX 格式的檔案互相轉換。

DOS/Windows 平台上的文字檔,每一列的結束符號有二個字元,分別是歸位字元13 (carriage return,^M)以及新列字元10 (new line,^J),,但 UNIX 平台則不同,UNIX 平台只使用一個新列字元 \n (^J)。因此,當您將 DOS 的文字檔欲放入 UNIX 平台時,應將 DOS 的結束符號換成 UNIX 的結束符號,否則 UNIX 平台上的應用程式可能會誤判,比如 vim 讀取 DOS 格式的文字檔時,會在每一列出現 ^M 的特殊符號(^M 就是 carriage return)

通常,當您使用 FTP 軟體上傳時,聰明的 FTP 軟體通常會幫您自動做轉換;或者,您也可以利用 unix2dos / dos2unix 程式來做轉換。這裡我們要介紹,如何用 Perl 來做到相同的功能。


27.1 DOS 轉成 UNIX
dos2ux.pl
引用:
#! /usr/bin/perl -i

while (<>) {
        s/\015\012//;
        print $_ . "\n";
}
用例:
引用:
./dos2ux.pl dos-test.txt

TOP

發新話題

本站所有圖文均屬網友發表,僅代表作者的觀點與本站無關,如有侵權請通知版主會盡快刪除。