Perl
Проверить, установлен ли модуль
Если модуль Digest::MD5 установлен команда
perl -MDigest::MD5 -e print
не скажет никакой ошибки а просто молча выполнится.
Скаляры
<highlightSyntax language="perl">
my $a; # $a создается, равно undef $a; # ложно defined($a); # ложно $a=0; $a; # ложно defined($a); # истинно $a=5; $a; # истинно defined($a); # истинно $a=undef; # опять undef!
</highlightSyntax>
Сравнения и циклы в Perl
Сравнения: <highlightSyntax language="perl">
$alpha = 1; $beta = 3 if $alpha > 0; # Результат: $beta = 3
if ($newspaper eq 'правда') {echo '$newspaper = правда'};
if ($newspaper ne $papername) {
echo 'newspaper это не papername';
$epsilon = 1;
if ($epsilon == 0) {
print "\$epsilon = 0\n";
}
elsif ($epsilon == 1){
print "\$epsilon = 1\n";
} else {
print "непонятно \$epsilon\n";
}
</highlightSyntax>
цикл While "пока" <highlightSyntax language="perl">
$gamma = 1; print $gamma++ while $gamma < 9; # Печать $gamma с инкрементом # Результат: 12345678
</highlightSyntax>
цикл Until "до" <highlightSyntax language="perl">
$delta = 1; print $delta++ until $delta > 7; # Печать $delta с инкрементом # Результат: 1234567
</highlightSyntax>
цикл For <highlightSyntax language="perl">
for ($i = 2; $i < 5; ++$i)
{
print $i, " ";
}
print "\nа после цикла i = $i\n";
# Результат: 2 3 4, после цикла i = 5
</highlightSyntax>
цикл Foreach
<highlightSyntax language="perl">
#!/usr/bin/perl sub max {
# перебрать все аргументы командной строки
# и вывести только максимальный из них
my $maximum = shift @$_;
my $x;
foreach $x (@_) {
$maximum=$x if ($x > $maximum) ;
}
return $maximum } print "Наибольший аргумент=", max(3,5,17,9), "\n";
</highlightSyntax>
Типы данных в Perl
Фильтр данных для CGI (данные полученные через веб формы)
Самые правильные фильтры от SQL Injection и прочих ошибок в значениях параметров. Данные фильтры отфильтруют из значений переменных все спецсимволы и оставят только буквы и цифры. Разумеется вы можете добавить в регулярные выражения нужные вам символы, помимо букв и цифр.
$String =~ s/[^0-9a-zA-Z]*//g; $Alpha =~ s/[^a-zA-Z]*//g; $Digit =~ s/[^0-9]*//g;
После фильтра вы можете задать дополнительные критерии для данных, например так:
$ParamError = 0
if (length($String) < 2){ $ParamError = 1 }; # длинна строки больше 2 символов
if (($Alpha ne "INSERT") or ($Type ne "UPDATE")){ $ParamError = 1 }; # содержится слово "INSERT" или "UPDATE"
if ($Digit < 1){ $ParamError = 1 }; # число меньше единицы
if ($ParamError == 1){ exit(1) };
Массивы и хэши в Perl
http://www.cs.mcgill.ca/~abatko/computers/programming/perl/howto/hash/
Дата и время
#!/usr/bin/perl -w
use POSIX 'strftime';
# Date format: YYYY-MM-DD
# in Unixtime:
# now = now in EPOCH
# 1 month = 30 days = 2592000 seconds
# 1 year = 365 days = 31536000 seconds
my $now = time();
my $yearago = $now - 31536000;
my $monthago = $now - 2592000;
my $datenow = strftime '%Y-%m-%d', localtime ($now);
my $dateyearago = strftime '%Y-%m-%d', localtime ($yearago);
my $datemonthago = strftime '%Y-%m-%d', localtime ($monthago);
print("$datenow, $dateyearago, $datemonthago \n");
Cтроки в Perl
Разделить строку на несколько переменных.
<highlightSyntax language="perl">
$mybigstring='Василий:Петров:идиот'
($name, $lastname, $status) = split(':');
</highlightSyntax>
LWP (встроенный браузер)
http://search.cpan.org/~gaas/libwww-perl-5.835/lib/LWP.pm
http://www.perl.com/pub/a/2002/08/20/perlandlwp.html?page=4
use LWP;
print $ENV{'http_proxy'};
# Create a user agent object
use LWP::UserAgent;
my $ua = LWP::UserAgent->new;
$ua->agent("TestProxy/0.1 ");
# Create a request
my $req = HTTP::Request->new(POST => 'http://search.cpan.org/search');
$req->content_type('application/x-www-form-urlencoded');
$req->content('query=libwww-perl&mode=dist');
# Pass request to the user agent and get a response back
my $res = $ua->request($req);
# Check the outcome of the response
if ($res->is_success) {
print $res->content;
}
else {
print "\n", $res->status_line, "\n";
}
Регулярные выражения RegExp
http://wdh.suncloud.ru/perl04.htm
http://genphys.phys.msu.ru/~dmitriyk/perl/regex.shtml
http://www.troubleshooters.com/codecorn/littperl/perlreg.htm
Пути библиотек lib
use Module::Submodule;
use lib ("/usr/lib/perl5/site_perl/5.8.8/");
require("/usr/lib/perl5/site_perl/5.8.8/XML/RSS/Parser/Lite.pm");
Встроенные переменные
Описанные в данной главе переменные имеют в Perl специальные значения. Они обозначаются несколько непривычно для "глаза" программистов, т.к. состоят обычно только из двух символов, причем первый это '$' символ, с которого начинаются имена всех переменных, и произвольный часто не буквенно-цифровой символ. Если вы хотите пользоваться их "нормальными" буквенными синонимами, то вам нужно указать в начале программы:
use English;
Точно так же если вы захотите пользоваться переменными и методами текущего указателя файлов вы можете написать:
use FileHandle;
после этого можно просто писать:
метод указатель выражение
или
указатель -> метод(выражение)
Ниже приводятся имена как в короткой, так и в длинной (словесной) форме. Некоторые из встроенных переменных имеют доступ только на чтение, поэтому изменить их значение просто невозможно.
$_ $ARG
Переменная - по умолчанию для операторов ввода и поиска. То есть если в качестве аргумента не указана никакая переменная, то используется именно эта.
$цифра
Содержит найденную подстроку в последнем поиске, когда шаблон содержит метасимволы в круглых скобках. Цифра в данном случае, это номер скобок. Первая подстрока имеет номер 1.
$& $MATCH
Найденная подстрока в последнем поиске по шаблону.
$`
Подстрока, предшествующая найденной подстроке.
$' $POSTMATCH
Подстрока, последующая за найденной подстрокой.
$+ $LAST_PAREN_MATCH
Подстрока, найденная в поиске с выбором по "или".
$* $MULTILINE_MATCHING
Если значение этой переменной установить равным 1, то переменная, в которой осуществляется поиск, будет считаться многострочной, т.е. содержащей символы '\n' - перевод строки. Если значение равно 0, то переменная считается однострочной. В Perl версии 5 и выше не рекомендуется использовать эту переменную.
$. $INPUT_LINE_NUMBER $NR
Номер прочитанной строки последнего оператора ввода. Закрытие файла вызывает очистку значения этой переменной.
$/ $RS $INPUT_RECORD_SEPARATOR
Символ - признак конца входной строки. По умолчанию это '\n'
$| $OUTPUT_AUTOFLUSH
Если присвоить этой переменной ненулевое значение, то будет сброс буфера вывода после каждой операции вывода. Значение по умолчанию - 0
$, $OFS $OUTPUT_FIELD_SEPARATOR
Символ, добавляемый оператором print после каждого элемента из списка параметров.
$\ $ORS $OUTPUT_RECORD_SEPARATOR
Символ, добавляемый print после вывода всех параметров.
$" $LIST_SEPARATOR
Аналогичен "$,", но добавляется после каждого элемента массива, указанного в "....".
$; $SUBSEP $SUBSCRIPT_SEPARATOR
Символ - разделитель для эмуляции многомерных массивов в хеш массивах. По умолчанию '\034'.
$# $OFMT
Формат по умолчанию для вывода чисел.
$% $FORMAT_PAGE_NUMBER
Формат по умолчанию для вывода номеров страниц.
$= $FORMAT_LINES_PER_PAGE
Длина одной страницы. По умолчанию 60 строк.
$- $FORMAT_LINES_LEFT
Количество оставшихся строк на странице.
$~ $FORMAT_NAME
Имя формата текущего вывода. По умолчанию имя указателя.
$^ $FORMAT_TOP_NAME
Имя текущего формата для заголовка страницы.
$: $FORMAT_LINE_BREAK_CHARACTERS
Символы переноса строки для многострочных полей. В строке формата такие поля начинаются символом '^'. По умолчанию '\n-'.
$^L $FORMAT_FORMFEED
Символ перевода формата ( смены листа). По умолчанию '\f'.
$^A $ACCUMULATOR
Текущее значение аккумулятора функции write() для format(). Значение этой переменной можно увидеть только при использовании функции formline(), т.к. write() очищает ее после каждого вывода.
$? $CHILD_ERROR
Данная переменная содержит статус завершения таких процессов как: закрытие pipe, завершение функций system(), wait() и `...`.
$! $ERRNO $OS_ERROR
В числовом контексте возвращает код ошибки errno. В строковом - строку сообщения об ошибке. Можно принудительно присвоить этой переменной код ошибки, что бы получить системное сообщение для данного кода или установить код завершения для функции die().
$@ $EVAL_ERROR
Сообщение об ошибке последней команды eval().
$$ $PID $PROCESS_ID
Номер текущего процесса.
$< $UID $REAL_USER_ID
Реальный UID текущего процесса.
$> $EUID $EFFECTIVE_USER_ID
Эффективный UID текущего процесса.
$( $GID $REAL_GROUP_ID
Реальный GID текущего процесса.
$) $EGID $EFFECTIVE_GROUP_ID
Эффективный GID текущего процесса.
$O $PROGRAM_NAME
Имя файла программы. Если этой переменной присвоить какое-нибудь значение, то его можно видеть в команде ps, что удобно для контроля за состоянием программы.
$[
Номер первого элемента массива или символа строки. Значение по умолчанию - 0.
$] $PERL_VERSION
Строка - сообщение версии Perl. Печатается по команде perl -v Применяется в программе для определения рабочей версии Perl. В числовом контексте это номер версии плюс номер модификации / 1000.
$^D $DEBUGGING
Текущее значение ключа отладки '-D'.
$^F $SYSTEM_FD_MAX
Номер максимального системного описателя файлов (system file descriptor). Обычно это 2.
$^I $INPLACE_EDIT
Текущее значение inplace-edit возможности. Для отключения используйте undef.
$^P $PERLDB
Внутренний флаг отладки. Применяется для того, чтобы отладчик не отслеживал самого себя.
$^T $BASETIME
Время в секундах с начала 1970 года старта текущей программы.
$^W $WARNING
Значение флага '-w'. true -если включено и false - выключено.
$^X $EXECUTABLE_NAME
Команда запуска Perl. Аналогично argv[0] в С.
$ARGV
Имя текущего файла, читаемого оператором '<>'.
@ARGV
Массив параметров строки запуска программы. Внимание! @#ARGV - меньше количества параметров на 1, т.к. $ARGV[0] это первый параметр (не имя программы).
@INC
Список директорий диска, которые просматривает Perl для выполнения команд do, require или use.
%INC
Этот хеш содержит имена директорий для имен использованных файлов командами do или require. Ключ - имя файла, а значение - директория.
$ENV{выражение}
Хеш %ENV содержит значения переменных окружения. Изменение этих значений вызывает изменение окружения для процессов потомков.
$SIG{выражение}
Хеш %SIG содержит имена подпрограмм для таких системных сигналов как INT, QUIT, PIPE, ... Значение 'DEFAULT' - для системной обработки. 'IGNORE' - игнорировать данный сигнал.
Функции в Perl
# This function for detection value
# input - sum of values (int)
# output - print every value description (text)
#
# example usage: GetValues(27);
#Dummy = 0,
#Rouble = 1,
#Dollar = 2,
#Euro = 4,
#Funt = 8,
#Yena = 16,
sub GetValues (int){
my($values) = $_[0];
my @ValuesDescriptions;
if ($values eq 0){ push (@ValuesDescriptions,"Dummy")};
if ($values &1){ push (@ValuesDescriptions,"Rouble")};
if ($values &2){ push (@ValuesDescriptions,"Dollar")};
if ($values &4){ push (@ValuesDescriptions,"Euro")};
if ($values &8){ push (@ValuesDescriptions,"Funt")};
if ($values &16){ push (@ValuesDescriptions,"Yena")};
foreach my $ValueDescriprion (@ValuesDescriptions){
print "$ValueDescriprion\n";
}
}
PID файлы - запуск одной копии программы
$pidfile = '/var/run/mydaemon.pid';
if (-e $pidfile) {
# PID-файл существует, но может быть создавший его процесс уже умер
unless (open(PIDFILE, $pidfile)) {
# слишком опасно стартовать, невозможно прочитать старый PID
exit(1);
}
my $oldpid=<PIDFILE>;
close PIDFILE;
# проверить, существует ли процесс с таким PID
if ($oldpid > 1 && kill(0,$oldpid)) {
# один экземпляр программы уже выполняется
exit(1);
} else {
# процесс, создавший файл, уже умер
}
}
# создать PID-файл
open(PID, ">$pidfile") or die;
print PID $$;
close(PID);
# выполнение программы
...
# удалить PID-файл
unlink $pidfile;
exit(0);
Распараллеливание fork()
my @Childs;
foreach my $Server (@Clusters) {
#fork() for every Server
my $pid = fork();
if ($pid) {push(@Childs, $pid)};
$PROGRAM_NAME = "child $pid - processing $Server";
if (not defined $pid) {
#print "resources not avilable.\n";
} elsif ($pid == 0) {
DO SOMETHING
}
foreach (@Childs) {
waitpid($_, 0);
}
при этом при запуске приложения будет примерно следующая картина:
server# ps | grep child 74011 p0 R+ 0:00.00 grep child 73725 p1 S+ 0:00.19 child 73748 - process A (perl5.8.9) 73730 p1 S+ 0:00.01 child 0 - process B (perl5.8.9) 73731 p1 S+ 0:00.01 child 0 - process C (perl5.8.9) 73739 p1 S+ 0:00.01 child 0 - process D (perl5.8.9) 73740 p1 S+ 0:00.01 child 0 - process E (perl5.8.9) 73741 p1 S+ 0:00.01 child 0 - process F (perl5.8.9) 73742 p1 S+ 0:00.01 child 0 - process G (perl5.8.9) 73743 p1 S+ 0:00.01 child 0 - process H (perl5.8.9) 73746 p1 S+ 0:00.01 child 0 - process I (perl5.8.9) 73747 p1 S+ 0:00.00 child 0 - process J (perl5.8.9) 73748 p1 S+ 0:00.00 child 0 - process K (perl5.8.9)
srv# pstree | grep child | | \-+- 76264 root child 76287 - process A (perl5.8.9) | | |--- 76267 root child 0 - process B (perl5.8.9) | | |--- 76269 root child 0 - process C (perl5.8.9) | | |--- 76270 root child 0 - process D (perl5.8.9) | | |--- 76273 root child 0 - process E (perl5.8.9) | | |--- 76276 root child 0 - process F (perl5.8.9) | | \--- 76287 root child 0 - process G (perl5.8.9)
Подсчет время выполнения программы/функции
# in begin
my $processingstart=time;
# profiling program code
for(my $I=1;$I<5;$I++){
sleep(10);
print "$I";
}
# in end
my $processingend=time;
my $processingtime = $processingend - $processingstart;
print "$processingtime\n";
Запуск команды Unix и получение её вывода
<highlightSyntax language="perl">
#!/usr/bin/perl # Show my current IP address $ifconfig=`/sbin/ifconfig rl1`; $ifconfig=~/inet\s(\S*)/; $ip=$1; print $ip, "\n";
</highlightSyntax>
Работа с файлами в Perl
#!/usr/bin/perl
open(PASS, "</etc/passwd") || die "Файл не найден!";
# Читать по одной строке файла в переменную по умолчанию $_.
while(<PASS>)
{
#Вывести переменную по умолчанию $_
print;
}
close(PASS);
чтение данных из файла с разделёнными полями (например для импорта из CSV)
open(DATAFILEDESC, "<datafile") || die "Error!";
while(<DATAFILEDESC>)
{
# datafile fields split by tab
my ($DataField1, $DataField2, $DataField3) = split('\t') ;
print "$DataField1, $DataField2, $DataField3" ;
}
close(DATAFILEDESC);
Запись в файл:
open (MYFILE, '>>data.txt'); print MYFILE "Bob\n"; close (MYFILE);
Работа с директориями в Perl
my $FOLDER='/home/user/somefolder';
chdir($FOLDER);
opendir(DIR, $FOLDER) or die "can't opendir $FOLDER: $!"; while (defined($file = readdir(DIR))){
if (($file ne '.') and ($file ne '..')){
my $filebasename = $file;
$filebasename =~ s{\.[^.]+$}{};
# do something with $file or $filebasename (without extension)
# i.e. mass rename, format conversion, ungzip, etc
}
} closedir(DIR);
работа с темплейтами
<!-HOST->
for(my $i=0; $i<=#$hosts; $i++)
{
open TEMPLATE, 'themplate-file'
$tmpl = <TEMPLATE>
$tmpl =~ s/<!-HOST->/$hosts[$i]/g;
}
Perl как CGI
HTML формы
СУБД MySQL
my $hash_ref = $dbh->selectall_hashref($Select,'ID'); print(Dumper($hash_ref));
Считать вывод результата MySQL (один столбец) в массив Perl
my $Select="select name from namestable";
my $query = $dbh->prepare($Select);
$query->execute;
my $rows = $query->rows;
my $I;
my @Names;
for ($I=0;$I<=$rows;$I++){
my $name = $query->fetchrow_array;
push @Names, $name;
}
СУБД Oracle
sample коннекта к оракловой базе из перла
use DBI;
#Для коннекта к ораклу из perl используется ТНС идентификатор, который берется из файла tnsnames.ora, его редактируют при помощи
#Oracle Enterprise Manager Console, он показывает его в строке Service при попытке коннекта к БД.
$tns_string="NSI_10.2.0.15";
# путь к инсталяции клиента оракла. (После инсталяции надо перегрузиться).
$ENV{'ORACLE_HOME'} = "C:\\oracle\\10.2.0_client";
$dbh = DBI->connect("dbi:Oracle:$tns_string", 'nsi', 'nsi', {RaiseError => 1, AutoCommit => 0})
|| die "Database connection error: $DBI::errstr";
$q="SELECT BBCODE FROM NSI_JURIDICAL_LOTTERY";
$sth=$dbh->prepare($q);
$sth->execute;
while($_=$sth->fetch) {
print @$_,"\n";
}
$dbh->disconnect;
Работа с XML
<highlightSyntax language="perl">
#!/usr/bin/perl -w
# Parse XML
use XML::Smart;
my $config = "accounts.xml";
my $doc = XML::Smart->new($config);
$doc = $doc->{config};
my $nodescount = @{$doc->{account}};
for (my $i=0; $i<$nodescount; $i++) {
my $login = $doc->{account}[$i]{login};
my $password = $doc->{account}[$i]{password};
print $login . ' ' . $password . "\n";
}
</highlightSyntax>
Работа с XML RSS
Generate RSS: http://perl-rss.sourceforge.net/
Parse RSS: http://search.cpan.org/~ebosrup/RSS-Parser-Lite-0.10/lib/XML/RSS/Parser/Lite.pm
Example: http://www.devshed.com/c/a/Perl/Build-a-Perl-RSS-Aggregator-with-Templating-Tools/1/
SOAP
OMPL
http://search.cpan.org/~madghoul/XML-OPML-0.26/OPML.pm
use XML::OPML; use Data::Dumper; # READ FEED LIST FROM OMPL local $/=undef; open FILE, 'feeds.ompl' or die "Couldn't open file: $!"; binmode FILE; $string = <FILE>; close FILE; my $opml = new XML::OPML; $opml->parse($string);
Работа с SysLog
http://perldoc.perl.org/Sys/Syslog.html
use Sys::Syslog;
openlog("testlog", "ndelay,pid", "local0");
syslog(LOG_WARNING, "782fhdfnv");
Data::Dumper
Модуль используется для печати данных во внутреннем представлении Perl (визуализация структур данных)
use Data::Dumper;
- $Data::Dumper::Indent = 0; # one-line output
- $Data::Dumper::Terse = 1; # print no assignments to $VARn
- $Data::Dumper::Useqq = 1; # quote unprintable chars
- $Data::Dumper::Deepcopy = 1; # ??? are we really need this? ;)
print Dumper($boo)
http://search.cpan.org/~ilyam/Data-Dumper-2.121/Dumper.pm
Data::Dumper::HTML
Модуль для печати структур данных в HTML
http://search.cpan.org/~dmuey/Data-Dumper-HTML-v0.0.2/lib/Data/Dumper/HTML.pm
Отладка
logger();
my ($a, $b, $c) = caller();
Random
String::Random
http://www.mathematik.uni-ulm.de/help/perl5/doc-5.005_03/String/Random.html
Отправка почты SMTP
#!/usr/bin/perl
use Mail::Sendmail;
%mail = ( To => 'mail@domain.tld',
From => 'mail@domain.tld',
Subject => 'Subj',
Message => "test",
SMTP => 'host.org'
);
sendmail(%mail) or die $Mail::Sendmail::error;
print "OK. Log says:\n", $Mail::Sendmail::log;
Работа с почтой Mbox
use Mail::Box;
use Mail::Box::Manager;
use Mail::Box::Mbox;
my $MAILBOX="/var/spool/mail/mailuser";
my $mgr = Mail::Box::Manager->new;
my $mbox=$mgr->open( folder => $MAILBOX,
lock_file => $MAILBOX,
lock_wait => 60,
lock_type => 'POSIX',
access => 'rw');
foreach my $id ($mbox->messageIds) {
$mbox->messageId($id)->print;
}
close($MAILBOX);
Или так:
my $message = $mbox->messageId($id); print $message->subject;
$message->delete;
Проверка наличия файла
$filename = '/path/to/your/file.doc';
if (-e $filename) {
print "File Exists!";
}
Win32 API (пример для Active Perl)
use Win32::API;
$LockStation = new Win32::API("user32", "LockWorkStation", , 'N');
$LockStation->Call();
Установка модулей
Модули ставятся через CPAN shell. Запускается он из Unix Shell командой:
perl -MCPAN -e shell
Любой модуль ставится командой
install module::submodule
Базовый набор ставится
install Bundle::CPAN
Обновление всех установленных модулей
upgrade
Настроить proxy auth
cpan> o conf init
Поменять mirror
cpan> o conf urllist push "http://www.cpan.org" cpan> o conf urllist shift cpan> o conf commit
Установка модулей Active Perl для Windows
http://docs.activestate.com/activeperl/5.10/faq/ActivePerl-faq2.html
Репозитории с бесплатными модулями:
http://www.bribes.org/perl/ppm/ http://theoryx5.uwinnipeg.ca/ppms/zips/ http://www.roth.net/perl/packages/ http://ppd.develop-help.com/ppd/Imager.ppd http://ppm.tcool.org/archives/ http://voltar.org/active/5.8/
внешние ссылки
Умные книги и статьи
http://www.opennet.ru/links/sml/13.shtml http://athena.vvsu.ru/inetcourse/labs/cgi-perl.html http://perl.dp.ua/qans/
Примеры из книг
http://perl.find-info.ru/perl/source.htm
Конструктор регулярных выражений
http://www.pcre.ru/eval/ http://www.opennet.ru/base/dev/perl_regex.txt.html
Графики и диаграммы с помощью GD:
http://www.providerz.ru/articles/perl/perl-using-gd-padala.html http://www.providerz.ru/articles/perl/perl-using-gd-padala-2.html
Работа с БД
http://sql-info.de/mysql/examples/Perl-DBI-examples.html http://www.providerz.ru/articles/perl/perl-database-dbi-usage.html http://search.cpan.org/~timb/DBI/DBI.pm
Работа с Template Toolkit (это круче чем HTML::Templates)
http://template-toolkit.ru/
Работа с HTML::Templates
http://www.providerz.ru/articles/perl/html-template.html
Работа с CGI::Session
http://search.cpan.org/~markstos/CGI-Session-4.14/lib/CGI/Session/Tutorial.pm
Работа с Getopt::Lucid
http://search.cpan.org/~dagolden/Getopt-Lucid-0.16/lib/Getopt/Lucid.pm
Работа с LWP (lib WWW)
http://www.opennet.ru/base/dev/perl_lwp.txt.html
Интересные советы:
http://www.opennet.ru/tips/sml/54.shtml

