Entries Tagged as 'Perl'

执行perl程序时load某个.so文件出错的问题

某天,碰到个perl的问题
执行某个perl程序的时候(这个程序通过DBD::Mysql连mysql数据库)
出错,具体出错提示忘了
大意思是:
load动态模块mysql.so的时候load其依赖的模块儿libssl.so.5失败(因为没有libssl.so.5这个文件)
我找了下
/lib/libssl.so.4/lib/libssl.so.6就是没有/lib/libssl.so.5
libssl.so.4和libssl.so.6其实是openssl的版本0.97a和0.98的东西
我在别的机器上翻了一下,发现/lib/libssl.so.5是openssl版本0.97f的东东
而我现在的系统(fc5, Fedora Core 5)下没有0.97f的openssl
这下好像陷入困境了
再仔细想想:
不对呀,我的DBD::Mysql也是yum装上的呀,如果它依赖于某个东西的话,yum怎么会没自动装上呢
就算某种原因没装上的话装DBD::Mysql的时候也应该会报错才对呀
再仔细看
发现了load的动态模块儿mysql.so是/usr/lib/perl5/site_perl/5.8.6/i386-linux-thread-multi/auto/DBD/mysql/目录下的
而load进这个mysql.so的却是/usr/lib/perl5/5.8.8/i386-linux-thread-multi/DynaLoader.pm这个文件
因为我的系统升过级
perl也由5.8.6升到5.8.8
但现在看来新perl(5.8.8) load的还是原来5.8.6下装的mysql模块儿
不对!
于是rpm -ql perl-DBD-MySQL一下
发现原来新的DBD::MySQL装的mysql.so是装在目录/usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi/auto/DBD/mysql/下的!!
但是加载DBD::MySQL的时候又怎么会跑去/usr/lib/perl5/site_perl/5.8.6/i386-linux-thread-multi/auto/DBD/mysql/mysql.so这里呢?

看了下/etc/ld.so.conf
发现有目录/usr/lib/
猜想:
会不会因为site_perl比vendor_perl优先被查找(字母’s’比’v'排在前面)
而以前perl 5.8.6的时候也手工安装过DBD::MySQL包
而且装在了site_perl下
所以load的时候就先找到了/usr/lib/perl5/site_perl/5.8.6/i386-linux-thread-multi/auto/DBD/mysql/mysql.so
而那会儿的mysql.so是依赖于libssl.so.5的
而现在系统没有/lib/libssl.so.5,所以出错
解决方法:
把/usr/lib/perl5/site_perl/5.8.6/i386-linux-thread-multi/auto/DBD/mysql/mysql.so删掉
于是问题解决

用CPAN安装perl包HTTP::Proxy的问题及解决

系统fedora core 4 + perl 5.8.6
用cpan模块儿(perl -MCPAN -e shell)安装perl包HTTP::Proxy的时候报错:

t/90diveintomark….ok 7/22# Failed test (t/90diveintomark.t at line 75)
# got: ‘500′
# expected: ‘302′
t/90diveintomark….ok 21/22 make: *** wait: No child processes. Stop.
make: *** Waiting for unfinished jobs….
make: *** wait: No child processes. Stop.
/usr/bin/make test — NOT OK
Running make install
make test had returned bad status, won’t install without force

到”t/90diveintomark….ok 21/22“这一步会停留很长时间
google了一把
发现HTTP::Proxy需要

HTTP::Daemon 1.36
LWP::UserAgent 2.033
Test::More 0.60

所以要求这几种包及其版本
然后我就install HTTP::Daemon
发现HTTP::Daemon is up to date.
然后install LWP::UserAgent
又是up to date.
最后install Test::More
这下开始安装了
OK后
再重新install HTTP::Proxy就没问题了

perl包IO::Socket::INET的timeout的问题

最近接触到个perl程序
其中用到了IO::Socket::INET这个包
看他的文档perldoc IO::Socket::INET
发现有Timeout这个参数
而且在程序里也设置了
但实际情况是
如果用这个包连上一个服务器之后
发命令
但服务器没有反应
也没有断开
这样的话好像程序也不断开

按照我的需求
应该是如果一段时间没有反应的话
程序应该主动断开才是呀
如果不能实现这个的话
那Timeout参数是做什么用的呢

大概看了一些网上的讨论
好像说这个Timeout是连服务器时的Timeout
如果一段时间没连上就超时
也不知道是不是真是这样
不过好像也只有这样才能解释我碰到的情况了

第一个用到多线程的perl程序

用来检查库里的代理列表是否依旧可用

多线程是用上了,但是不知道缺省是起几个线程

:(

#!/usr/bin/perl

use strict;

use DBI();

use HTTP::ProxyCheck;

use threads;

my $DEBUG = 1;

# Connect to the database.

my $TimeToLive = 5;     # 3 days

my $dbh = DBI->connect("DBI:mysql:database=proxyservers;host=localhost;mysql_socket=/var/lib/mysql/mysql.sock",

                        "root", "", {’RaiseError’ => 1});

my $sql = "select id, ipn, port from proxy where now() - INTERVAL 1 day > t_checked order by t_checked";

print $sql if ($DEBUG);

my $sth = $dbh->prepare("$sql");

$sth->execute();

while (my $ref=$sth->fetchrow_hashref()) {

        my $thr = threads->new(\&CheckHTTPProxy, "$ref->{’ipn’}", "$ref->{’port’}");

        if ($thr->join) {

#       if (CheckHTTPProxy($ref->{’ipn’}, $ref->{’port’})) {

                $sql = "update proxy set t_checked = now() where id = $ref->{’id’}";

                print $sql if ($DEBUG);

                $dbh->do("$sql");

        }

}

$sql = "delete from proxy where now() - INTERVAL $TimeToLive day > t_checked";

print $sql if ($DEBUG);

$dbh->do("$sql");

$dbh->disconnect();

sub CheckHTTPProxy

{

        my ($ipn, $port) = @_;

        my $ip = num2str($ipn);

        my $proxy = "$ip:$port";

        my $url = ‘http://search.cpan.org/’;

        my $proxy_check = new HTTP::ProxyCheck(

                proxy           => $proxy,

                url             => $url,

                answer_size     => ‘header’,

                print_error     => 0,

        ) or return 0;

        print "Trying to connect to ‘$proxy’ and retrieve ‘$url’\n" if ($DEBUG);

        if ( $proxy_check->check() ) {

                print "’$proxy’ returns:\n\n", $proxy_check->get_answer(), "\n\n" if ($DEBUG);

                return 1;

        } else {

                print "Error: ", $proxy_check->get_error(), "\n" if ($DEBUG);

                return 0;

        }

}

sub num2str

{

        my ($ipn) = @_;

        my $z = $ipn % 256;

        $ipn >>= 8;

        my $y = $ipn % 256;

        $ipn >>= 8;

        my $x = $ipn % 256;

        $ipn >>= 8;

        my $w = $ipn % 256;

        return "$w.$x.$y.$z";

}

perl的运算符x

有时候需要在shell里生成多少个重复字符的字符串

用perl的这个运算符就非常方便

比如

perl -e ‘print "a" x 100′

这将会打印100个字符"a"

perl的官方文档里是这么讲的:

Binary "x" is the repetition operator. In scalar context or if the left operand is not enclosed in parentheses, it returns a string consisting of the left operand repeated the number of times specified by the right operand. In list context, if the left operand is enclosed in parentheses or is a list formed by qw/STRING/, it repeats the list. If the right operand is zero or negative, it returns an empty string or an empty list, depending on the context.

    print '-' x 80;             # print row of dashes
print "\t" x ($tab/8), ' ' x ($tab%8);      # tab over
@ones = (1) x 80;           # a list of 80 1's
@ones = (5) x @ones;        # set all elements to 5

用perl程序监测应用的log发现的怪问题

前几天做一个perl程序

用来监控一个应用生成的log文件

当log里报什么什么的时候

把报的有用的东西处理一下

发到合适的地方



实现方法是用tail -f这个log文件

然后再用管道符"|"传给这个perl程序

结果发现这样可以

但是如果我tail -f这个log文件后

不用管道"|"直接传给perl程序

而是先用grep处理一下

然后再用管道符"|"传给perl程序

这样好像就有问题

perl程序好像根本就接收不到数据



于是我做了下测试

我写了这样一个perl程序:


#!/usr/bin/perl



while(<STDIN>) {

        print "perl:$_";
}



然后tail -f a.log | ./a.pl

这样可以输出所有信息

每行前都加有"perl:"字样

但是当我tail -f a.log | grep xxxx | ./a.pl

这样的时候

系统没有输出

但如果去掉a.pl

tail -f a.log | grep xxxx

这样也是会有很多输出的

为什么会这样呢

一个从xml文件向mysql数据库里倒数据的perl程序


#!/usr/bin/perl

use strict;
use DBI;
use XML::Parser;

# create hash to hold values for expected column names
my %row = (
"key" => undef,
"name" => undef);

# connect to database and create parser object
my $dbh = DBI->connect ("DBI:mysql:ipmap",
"root", "passwd",
{ RaiseError => 1, PrintError => 0});
my $parser = new XML::Parser (
Handlers => {
Start => \&handle_start,
End => \&handle_end,
Char => \&handle_text
}
);

# parse file and disconnect
$parser->parsefile ("example.xml");
$dbh->disconnect ();

sub handle_start
{
my ($p, $tag) = @_; # parser, tag name

if ($tag eq "row")
{
foreach my $key (keys (%row))
{
$row{$key} = undef;
}
}
}

sub handle_text
{
my ($p, $data) = @_; # parser, text

my $tag = $p->current_element ();
$row{$tag} .= $data if exists ($row{$tag});
}

sub handle_end
{
my ($p, $tag) = @_; # parser, tag name

if ($tag eq "row")
{
my $str;
# construct column assignments for INSERT statement
foreach my $key (keys (%row))
{
$str .= "," if $str;
$str .= "$key=" . $dbh->quote($row{$key});
}
$dbh->do ("INSERT INTO ipmap SET $str");
}
}

用cpan来安装perl的模块儿

常用

但也记不住

每次都得查manual

perl -MCPAN -e shell

CPAN(Comprehensive Perl Archive Network)

全面的perl存档网络?

呵呵

第一次运行这个命令的时候可能会需要需要回答一些问题

最后保存为一个设置

如果你的机器直接通internet

那么直接回车下去就可以了