Чем отличается синтаксис скриптов на UNIX и WIN платформах?
Ответ:
Юниксовый Perl плохо воспринимает досовский перевод строки - CR LF. Если открыть такой файл в vi в конце строк будут ^M. Удалить их можно, например таким скриптом:
При этом "что то там" - это имя области авторизации, по правилам для области с одним именем должен всегда срабарывать один и тот же пароль. Проблема заключается в том, что ответ пользователя сидит в заголовке HTTP-запроса, в поле Authorization, которое скрипту через переменные окружения не передаётся. Для сервера Апаче эта проблема решается прописыванием в файле конфигурации следующих строк:
RewriteEngine on
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule ^(.*) - [E=HTTP_CGI_AUTHORIZATION:%1]
Всё что он делает - это добавляет в переменную окружения HTTP_CGI_AUTHORIZATION, в которую пишется содержимое HTTP заголовка Authorization, таким образом означенное поле становится доступным для анализа внутри скрипта. Формат этого поля следующий: "login:password", причём эта строка закодирована в Base64, получить эти составляющие можно так:
use MIME::Base64;
$ENV{HTTP_CGI_AUTHORIZATION} =~ s/basic\s+//i;
($REMOTE_USER,$REMOTE_PASSWD) = split(/:/,decode_base64($ENV{HTTP_
CGI_AUTHORIZATION}));
Я пытаюсть скриптом вывести картинку, а мне вместо нее выдается стандартная битая картинка браузера.
Ответ:
В этом есть две причины, во-первых необходимо выдавать правильные заголовки, во-вторых на некоторых веб-серверах необходимо переводить потоки ввода-вывода в бинарный режим, лучше это делать всегда. Если Вы берете файл из картинки, можете воспользоваться следующим примером:
print "Content-type: image/gif\n"; # Для JPEG будет
print "Content-length: 7256\n\n";
open (IMG1,"image.gif");
binmode IMG1;
binmode STDOUT;
print ;
close (IMG1);
Заголовок Content-length в принципе необязателен, но желателен. Он должен содержать реальный размер файла в байтах. Его можно получить воспользовавшись конструкцией -s
Как сделать upload картинки через форму?
Ответ:
use CGI qw/:standard/;
# Код для формы
print "Content-Type: text/html\n\n";
print <
<'head'><'title'>file upload<'/title'><'/head'>
<'form method="post" enctype="multipart/form-data" action="upload.pl"'>
<'input type="file" name="picture"'>
<'input type="submit" name="Submit" value="Submit"'>
EOF
if(param()){&insert_image(1);}
sub insert_image
# путь к директории для закачки
$downpath = "download/";
my $in=param('picture');
# выделяем имя файла из параметра
@fname = split(/\\/,$in);
$kk = @fname;
$name = $fname[$kk-1];
open OUT, (">$downpath$name");
binmode(OUT);
# читаем входной поток и пишем в файл (файл в binmode!!!)
le(<$in>){
print OUT $_;
}
close(OUT);
# выводим надпись о закачке файла <$name>
print "<'h2'>Upload file: $name<'/h2'>";
};
Где можно взять Perl?
Ответ:
На CPAN == Comprehensive Perl Archive Network. Homepage CPAN -- http://www.cpan.org/ -- там берут все, связанное с перлом. Собственно исходники новейшей версии перла берут из файла http://www.perl.com/CPAN/src/latest.tar.gz (на самом деле с www.perl.com стоит редирект на ближайший, по мнению www.perl.com, mirror).
Я скачал модуль Lib::Module. Как его установить?
Ответ:
Обычно модуль приходит в формате tar+gzip, типа module-0.01.tar.gz. Вам необходимо его развернуть:
gzip -dc module-0.01.tar.gz | tar xf -
и перейти в образовавшуюся директорию, например module-0.01:
cd module-0.01
Обычно там находятся несколько файлов. Для вас будут важными следующие:
README - что это за модуль
INSTALL - как его поставить
Makefile.PL - перловый скрипт для генерации Makefile
Обычно инсталляция происходит следующим образом:
perl Makefile.PL - генерация Makefile
make all - сборка модуля
make test - тестирование модуля
make install - инсталляция модуля
Необходимо внимательно смотреть, не возникли ли какие ошибки во время первых трех команд. Внимание: вы должны иметь административные привелегии для инсталлирование модуля в системе (обычно как root). Но, если вы их не имеете, то можете инсталлировать модуль у себя. Для этого вам необходимо выбрать, где это будет делаться. Для примера, в $HOME/lib/perl5. Необходимо создать эти директории, если их нет:
mkdir ~/lib
mkdir ~/lib/perl5
Затем, при генерации Makefile для модуля, вы должны указать, где вы хотите инсталлировать модуль:
perl Makefile prefix=$HOME
Все остальные шаги без изменений. В результате вы получите альтернативное место, где у вас будут находиться модули. Например, у меня это выглядит так:
artur@disco:~ (681) ls -alFg ~/lib/perl5/
total 704
drwxr-sr-x 8 artur staff 512 Oct 06 15:53 ./
drwxr-sr-x 9 artur staff 1024 Oct 08 10:50 ../
drwxr-sr-x 4 artur staff 512 Mar 31 1998 aix/
drwxr-sr-x 2 artur staff 512 Aug 06 13:40 CPAN/
-r--r--r-- 1 artur staff 126951 Jul 24 19:37 CPAN.pm
drwxr-sr-x 3 artur staff 512 Mar 31 1998 man/
drwxr-sr-x 31 artur staff 1024 Sep 09 15:41 site_perl/
Для того, чтобы их использовать, есть несколько путей: 1. указывать при запуске perl в командной строке:
для sh (bash,zsh,ksh)
PERL5LIB=$HOME/lib/perl5:$HOME/lib/perl5/site_perl
export PERL5LIB
для csh (tcsh)
setenv PERL5LIB $HOME/lib/perl5:$HOME/lib/perl5/site_perl
3. указывать в начале скриптов дополнительные библиотеки:
use lib "/home/you/lib/perl5";
use lib "/home/you/lib/perl5/site_perl";
Данный случай подходит к CGI-скриптам, которые не наследуют ваших переменных окружения.
Как автоматизировать процесс установки библиотек и модулей?
Ответ:
Скачивание и установка вручную -- достаточно сложное занятие, требующее постоянного вмешательства с вашей стороны. Можно простым способом: сделать su (желательно), набрать perl -MCPAN -e shell. Если это первый запуск модуля CPAN, вам задатут серию вопросов на тему URL вашего любимого зеркала CPAN. После этого все просто: если вы знаете название модуля или библиотеки, то набираете, скажем, install Net::NNTP. Тогда этот модуль (для работы с NNTP) сам ищется на CPAN, сам скачивается, компилируется, устанавливается. Все, поставили, можно выходить и использовать вновь установленный модуль. Если название точно не известно, то набираем там же help и испльзуем различные команды поиска типа i NNTP.
Где взять стандартную документацию про такое-то свойство Perl?
Ответ:
Перл приходит с полным набором документации и набором программ для переведения в разные форматы. Обычно для подробного ознакомления с некоторой особенностью перла пишут "perldoc perlсвойство" или "man perlсвойство". Базовый набор "свойств" таков:
Основы perldata, perlvar, perlsyn, perlop, perlsub
Запуск perlrun, perldebug
Функции perlfunc
Objects perlref, perlmod, perlobj, perltie
Data Structures perlref, perllol, perldsc
Modules perlmod, perlmodlib, perlsub
Regexps perlre, perlfunc, perlop, perllocale
Moving to perl5 perltrap, perl
Linking w/C perlxstut, perlxs, perlcall, perlguts, perlembed
Various http://www.perl.com/CPAN/doc/FMTEYEWTK/index.html
(not a man-page but still useful)
perl О перле вообще
perldelta Что нового в последней версии перла
perlfaq FAQ
perltoc Подробное оглавление ко всей документации
perldata Типы данных
perlsyn Синтаксис языка
perlop Арифметические, логические, строковые
операции и их приоритет
perlre Регулярные выражения (обработка текста и поиск)
perlrun Опции командной строки
perlfunc Встроенные функции
perlvar Специальные переменные
perlsub Как писать свои функции (процедуры)
perlmod Устройство и принцип работы модулей
perlmodlib Модули: создание собственных библиотек
perlmodinstall Поиск и установка модулей и библиотек на CPAN
perlform "Форматы", или шаблоны для выводимых данных
perllocale Поддержка интернационализации
perlref Ccылки и указатели на данные
perldsc Введение в структурные типы данных
perllol Структуры данных: массивы и списки
perltoot Введение в объектно-ориентированное
программирование
perlobj Объекты в перле
perltie Связь объектов с обыкновенными переменными
perlbot Perl OO tricks and examples
perlipc Связь между процессами: pipes, sockets,
сигналы и др.
perldebug Отладка программ
perldiag Сообщения об ошибках
perlsec Вопросы безопасности
F
perltrap Возможные грабли и ловушки
perlport Как писать портабельные программы
perlstyle Стиль программирования на перле
perlpod Формат стандартной документации и документация,
встраиваемая в исходные тексты программ
perlbook О книгах про перл
--- (для совсем крутых) ---
perlembed Способы внедрения перл-программ в программы на C/C++
perlapio Собственный API, использумый в исходниках перла
perlxs XS -- программирование перловских библиотек,
используемых вместе с библиотеками на C
perlxstut Учебник по XS
perlguts Внутренние функции перла для разработчиков
perlcall Соглашения о вызове перловских функций из C
perlhist История и полный список всех версий перла
Где взять описание модуля Lib::Module?
Ответ:
Формат стандартной документации по перлу (pod) обладает возможностью встраивания прямо в тексты программ, а программа perldoc -- возможностью извлечения этой документации. Поэтому, чтобы получить документацию по модулю Math::Trig, просто наберите perldoc Math::Trig -- perldoc найдет этот модуль и покажет документацию из него. Если модуль не является частью какой-то библиотеки, а существует сам по себе, например, CGI.pm тогда просто perldoc CGI.pm или даже perldoc CGI. NB: программа perldoc не очень расторопна, поэтому при установке перла под UNIX производится создание manpages для всех модулей, так что man CGI или man Math::Trig покажет быстрее, чем perldoc.
Как пользоваться функцией pack (getpwuid, dmbopen)?
Ответ:
man perlfunc или "perldoc -f имя_функции | pod2text" Пара примеров для unpack: Определение типа изображения и его размеров:
sub get_image_spec {
# Возвращает ($Тип_изображения, $ширина, $высота)
my $buf = $_[0];
my ($type, $width, $height);
if (unpack("n", $buf) == 0xffd8) {
return ('jpeg', 0, 0); # Про jpeg я пока не знаю как
# определить его размеры
} elsif (unpack("A4", $buf) eq "GIF8") {
my ($type, $width, $height) = unpack("A6 v v", $buf);
return ('gif', $width, $height);
}
}
read(STDIN, $buf, 120);
print join (", ", get_image_spec($buf));
Как узнать размер файла (дату создания, атрибуты, разрешения на доступ)?
Ответ:
С помощью так называемых файловых тестов, которые имеют вид (-тест "имя файла"), например:
(-s "file.txt") размер файла
-e существует ли файл
-w доступен ли на запись
-M количество дней со дня модификации
-t является ли терминалом
Как отправить почту из скрипта на Perl?
Ответ:
Способ для Unix
----
open MAIL, '|/path/to/your/sendmail -t'; # Pipe к sendmail
print MAIL "From: [email protected]\n",
"To: [email protected]\n",
"Subject: Wow! I got some mail for you!!!\n\n",
$message;
close MAIL;
-----
Подробности: man sendmail, http://www.sendmail.org У меня не Unix! Что делать? Вероятно, Вам поможет модуль Net::SMTP
Как написать модуль?
Ответ:
Простейший случай: Сам модуль представляет из себя файл с именем MyModule.pm следуещего содержания:
package MyModule;
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(идентификаторы для экспорта:
подпрограммы, имена переменных и
пр.);
# Теперь после того, как вы напишите
#use MyModule в своей программе, у вас все
# упомянутые здесь идентификаторы станут видны.
# Этот метод не рекомендуется,
# так как вы "засоряете" именное пространство программы.
# И/или
@EXPORT_OK = qw(идентификаторы для экспорта:
#подпрограммы, имена переменных и
пр.);
# Идентификаторы, прописанные здесь будут видны
# в Вашей пргорамме как
# MyModule::Идентификатор (подпрограммы) или
#$MyModule::Идетификатор
# (переменные)
# Или, Вы можете написать use MyModule
#qw(Ид1 Ид2 $Ид3); и все будет как в
# первом случае. Это рекомендуемый вариант.
... ваши подпрограммы и пр ....
1; # Обязательно
# конец МойМодуль
Программа, его используящая:
use MyModule qw(...);
# Ну и далеее
Подробности смотрите в perlmod(1), Exporter(3pm), Camel Book
Как получить доступ к n-му сиволу строки?
Ответ:
Надо использовать функцию substr. Например, получить 15й символ из строки $string:
$char = ;
Установить 15й символ строки $string:
= 'A';
Можно даже использовать болле чем односимвольные последовательности:
$ss = ;
= 'Хо-Хо';
Под какие платформы существует Perl?
Ответ:
perl 5 - под практически все виды UNIX-систем (Linux, FreeBSD, SunOS,..), DOS (защищенный режим, i386 и выше), Windows 9x/NT, OS/2, VAX VMS, Novell Netware, Amiga.
А где взять компилятор?
Ответ:
Пока полноценных компиляторов не существует - скрипты выполняются и распространяются в виде исходников. Hечто, заявленное, как компилятор, и подходящее только к Activestate-перлу для w32, лежит на www.activestate.com
Как сделать то-то? Может, уже есть готовая библиотека?
Ответ:
http://www.perl.com/CPAN/ , http://search.cpan.org/ CPAN - огромное, отсортированное собрание всех дополнительных модулей к perl, не включенных в поставку. Собраны все версии модулей. Рядом с ними лежат readme. Скачиваете, и устанавливаете. В 90% случаев то, что вы пытаетесь сделать, уже кто-то сделал и выложил на CPAN.
Где взять скриптов готовых, побольше?
Ответ:
Здесь много скриптов и ссылок на них!
Какую книгу для начинающих посоветуете?
Ответ:
Llama Book, она же "Изучаем перл" в русском издании. С ламой на обложке. А также "Perl Специальный справочник" Стивена Холзнера. Все эти книги можно посмотреть на нашем сайте здесь.
Как прикрутить perl к винде, чтобы можно было скрипты выполнять локально?
Ответ:
http://www.activestate.com/, download perl. Устанавливаете, и запускаете:
perl myscript.pl
У меня перл от Activestate, как мне поставить такой-то модуль?
Ответ:
www.activestate.com/packages/zips/ Hаходите нужный архив, скачиваете, читаете readme. Если нужного модуля нет - ставите MS Visual C, и мучаетесь, мучаетесь..
А из браузера как смотреть на вывод скрипта? Почему-то показывается исходник.
Ответ:
Потому что между браузером и perl должен стоять сервер, который и запускает скрипт на выполнение, отдавая результат браузеру. Сервер не обязательно подразумевает под собой отдельный компьютер - вы можете поставить себе программу, и обращаться к ней через браузер, наблюдая за работой скриптов. Вариантов масса:
Personal Web Server из поставки Win9x
Sambar, http://www.sambar.com/
Apache-W32, http://www.apache.org/
Устанавливаете сервер, и либо указываете в настройках сервера ассоциацию на файлы cgi и pl - запуск perl.exe, либо устанавливаете такую ассоциацию на эти файлы в windows (dbl click в windows explorer AKA проводник).
А что это за закорючки такие в скрипте - s/^[^\w]{1,3}(\d+)/$1/
Ответ:
Это регулярные выражения, одна из мощнейших возможностей perl. Средства поиска и замены подстрок в строках
Как ими пользоваться?
Ответ:
Этому учатся всю жизнь. Даже целая книга есть - "Mastering regular expressions". Также следует прочесть perldoc perlre А начать можно со следующего:
// - поиск
s/// - поиск и замена
tr/// - трансляция
Если мы хотим узнать, нет ли в строке
$_ подстроки 'my', мы пишем:
/my/;
Если мы имеем дело не с переменной по
умолчанию, а с любой другой, пишем:
$str=~/my/;
Если мы хотим заменить в строке подстроку
tree на root, используем поиск и замену:
$str=~s/tree/root/;
В конце выражения могут стоять опции g, i и т.п. g означает проводить замену не 1 раз, а по всей подстроке. i означает не учитывать регистр символов. В подстроке для поиска можно использовать управляющие символы. Есть два вида управляющих символов - мета-символы, обозначающие какой-то символ из набора букв, цифр, и т.п., и мета-символы, управляющие количеством. Hапример, \d в подстроке обозначает любую цифру, \w - любую букву, \s - пробел, . - любой символ. Стоящая после мета-символа * означает, что предыдущий символ может повторяться 0 или более раз. + означает повторение 1 или более раз. То есть, строка вида
$str=~s/\s\d+\s/\s1\s/g;
означает "заменить все числа в строке $str, отделенные пробелами с двух сторон, на цифру 1, отделенную пробелами". Более подробное описание регулярных выражений, список управляющих символов и других возможностей смотрите в документации
Как не учитывать регистр в русском тексте? С английским регекспы с ключом i работают, а с русским - нет.
Ответ:
Hа Linux-е это делается так:
use locale;
use POSIX qw (locale_h);
setlocale(LC_CTYPE, 'ru_RU.KOI8-R');
(можно еще выставить переменную окружения export LANG=ru_RU.KOI8-R тогда будет достаточно вызова use locale; в Perl-скрипте) Под Windows это делается так:
use locale;
use POSIX qw (locale_h);
setlocale(LC_CTYPE, "Russian_Russia.1251"); # или "Russian_Russia.866"
С трансляцией АКА tr/XX/xx/ даже не используя use locale; можно так сделать:
tr/\xB3\xE0-\xFF/\xA3\xC0-\xDF/; # для KOI8-r
или
tr/\xA8\xC0-\xDF/\xB8\xE0-\xFF/; # для Windows-1251
или
tr/\xF0\x80-\x9F/\xF1\xA0-\xAF\xE0-\xEF/; # для CP-866
Как работать из perl с базами данных?
Ответ:
DBI. Это унифицированный программный интерфейс, придуманный для того, чтобы с разными базами можно было работать одинаково (за исключением, конечно, специфики самих SQL-запросов). Устанавливаете модуль DBI, ищете и устанавливаете DBD - драйвер-связку между DBI и нужной вам базой. Orcale, MySQL, Postgres и куча других СУБД поддерживаются DBI+DBD. Читаете perldoc DBI.
Хочу прочитать список файлов в каталоге, но почему-то не работает или глючит. Делаю так: @files=<*>;
Ответ:
Такой способ вызывает внешнюю программу glob (также, как и способ @files=glob("*")). Это неправильно не только потому, что на запуск внешней программы уходит время и ресурсы, но и потому, что где-нибудь этой программы может просто не оказаться. Более правильный способ - это:
opendir DIR,'/tmp';
@files=readdir DIR;
closedir DIR;
или
opendir DIR,'/tmp';
while $file (readdir DIR)
{
}
closedir DIR;
Заметьте, что в $file будут подставляться как имена файлов, так и имена подкаталогов. Несколько подсказок. Чтобы прочесть список файлов, в котором не содержалось бы '.' и '..', можно написать следующее:
Я положил скрипт на сервер, ввожу его путь в браузер, но вместо того, чтобы выполнять скрипт, браузер выводит его исходный текст.
Ответ:
В этом есть две причины, во-первых необходимо выдавать правильные заголовки, во-вторых на некоторых веб-серверах необходимо переводить потоки ввода-вывода в бинарный режим, лучше это делать всегда. Если Вы берете файл из картинки, можете воспользоваться следующим примером: Чтобы сервер запускал скрипт и выдавал результаты его работы, необходимо объяснить серверу, что этот файл - исполняемый. Существующее в unix-системах понятие "атрибуты файла" отличается от атрибутов в DOS/Windows, и в unix исполняемый файл определяется не расширением, а атрибутом. Если сервер работает на unix-системе, необходимо проставить на файл атрибуты исполняемого файла. Это делает команда "chmod 0755 file", если вы работаете через telnet или ssh, или же продвинутый FTP-клиент типа CuteFTP или FAR ftp plugin. Атрибуты файла, который могут исполнять все желающие (в том числе и сервер), выглядят в буквенном представлении, как
-rwxr-xr-x
При попытке запустить скрипт происходит Internal Server Error! Что это за ошибка?
Ответ:
Это, строго говоря, просто сообщение об одной из ошибок, приведших к невозможности нормального выполнения скрипта. Чаще всего возникает в следующих случаях:
в первой строке нет или неправильно указан путь к perl.
обычно это
#!/usr/local/bin/perl или #!/usr/bin/perl
Файл со скриптом содержит DOS-овые концы строк 0x0D 0x0A.
В юниксе конец строки - только 0x0A. Чтобы исправить это,
воспользуйтесь соотв. возможностью редактора FAR, или при
закачке скрипта на ftp используйте ASCII-режим вместо бинарного.
Скрипт не выводит ничего во время работы. Hеобходимо,
чтобы он выводил хотя-бы content-type заголовок, например:
print "Content-type: text/html\n\n";
print "All done";
Обратите внимание на двойной перевод строки в конце заголовка.
Если у вас нет доступа к логу ошибок сервера, для отладки
скрипта используйте директиву
use CGI::Carp qw (fatalsToBrowser);
В этом случае при фатальной ошибке, приводящей к завершению скрипта,
эта ошибка будет видна вам в браузере.
А можно ли узнать IP юзера, запустившего скрипт через прокси?
Ответ:
: $ENV{'HTTP_X_FORWARDED_FOR'}. Hо не все прокси обеспечивают IP сидящего за ними юзера. "Честные" прокси,- у провайдеров, например,- это делают. А некоторые халявные прокси-сервера, могут и не показывать IP сидящего "за" ними пользователя.
Как запускать скрипт на сервере через определенные промежутки времени, или в определенное время суток, день недели, месяц?..
Ответ:
Это возможно, если есть шелл-доступ на сервер. Читайте man crontab
Можно ли проверить, жив ли определенный e-mail адрес?
Ответ:
В общем случае - нельзя. Проверка существования и функционирования домена, в котором этот email прописан, в сущности ничего не дает. Остается отталкиваться от конкретных требований. Например, послать e-mail на этот адрес и попросить ответить, зафиксировав ответ.
Почему в тексте html, выводимом скриптом, не работают директивы SSI?
Ответ:
Потому что выполнение директив SSI происходит только в тех статичных html-файлах, обработка которых задана в конфигурации сервера.
Что такое mod+perl?
Ответ:
Hа пальцах - модуль к серверу Apache, который предназначен в первую очередь для ускорения запуска скриптов. Вместо того, чтобы каждый раз при запуске скрипта запускался perl, компилировал скрипт и выполнял его, этот perl все время запущен, и висит в памяти. В памяти же находятся и уже откомпилированные до состояния исполняемого кода скрипты.
Hаписание скриптов под mod_perl чем нибудь отличается от написания обычных CGI скриптов?
Ответ:
Вообще говоря, да. Во-первых, существует куча более других способов писания под mod_perl - Perl-SSI, Perl*Handlers, логика работы которых сильно отличается от CGI. Если же мы говорим о тех скриптах, которые выполняются через Apache::Registry, то есть следующие различия: 1. Hельзя использовать my-переменные уровня файла. То есть использовать можно, но результат будет ну очень странный. Дело в том, что с точки зрения перла, mod_perl-овый скрипт это не файл, а тело процедуры. Поэтому использование в нем my переменных, которые потом пользуются из вложенных процедур, приводит к возникновению closure и всему, что из этого следует. Я лично исполюзую следующую технику:
use CGI;
use DBI;
use strict;
use что-там-еще-надо
&main;
sub main {
my $cgi=new CGI;
....
}
sub some_more_sub {
...
}
При таким образом написанном скрипте я уверен что lexical scoring будет вести себя одинаково и в CGI и в mod_perl. 2. Скрипты живут долго. Поэтому мусор за собой надо чистить аккуратно. 3. Тебе доступен объект Apache::Request, который содержит уйму интересной информации; в частности, из него можно вытащить пароль при basic authentication. 4. Теоретически, у тебя есть куда больше способов повлиять на поведение Apache в процессе обработки твоего запроса, чем из CGI. 5. Если ты используешь самописные модули, то при их редактировании придется апач перестартовывать (apachectl restart)
Как сделать так, чтобы скрипт работал в фоновом режиме, как демон?
Варианта два. Первый - воспользоваться модулем Proc::Daemon, второй - сделать все самому, примерно так:
use strict;
require 'sys/syscall.ph';
# Устанавливаем путь по умолчанию
$ENV{PATH} = '/bin:/usr/bin';
# Чисто для прикола
$0='mydaemon';
# Отделяемся от родителя
fork() && exit;
# Отключаемся от терминала
close STDOUT; close STDERR; close STDIN;
# Делаем корень текужим каталогом
chdir '/';
# Создаем новую сессию и становимся лидером
# группы процессов, чтоб нас случайно не прибили
syscall(&SYS_setsid);
# Перехватываем сигналы, для корректного выхода
$SIG{'INT'} = $SIG{'QUIT'} = $SIG{'TERM'} = 'quit';
$SIG{'HUP'} = 'ignore';
# Делаем наши темные дела
...
# Выходим
quit();
sub quit {
# Помещаем сюда код для корректного
# прекращения работы
...
exit(0);
}
Если Вы хотите написать демона, реализующего работу через сеть, рекомендуем ознакомиться с модулем Net::Daemon.
Как сдеалать так, чтобы программа гарантированно работала только в одном экземпляре?
Способ первый, принятый в мире Unix:
$pidfile = '/var/run/mydaemon.pid';
if (-e $pidfile) {
# aha, pid file is here, but process could be dead by now
my $myfile=file_name($0);
unless (open(PIDFILE,$pidfile)) {
# too dangerous to start because I can't read old PID
exit 1;
}
my $oldpid=;
close PIDFILE;
# see if there is a process with such pid
if ($oldpid > 1 && kill(0,$oldpid)) {
# another proccess is running already
exit 1;
} else {
# that process is long dead
}
}
# write pid file
open (PID, ">$pidfile") or die;
print PID $$;
close(PID);
# do some work
...
# remove pid file
unlink $pidfile;
exit(0);
Способ второй, основанный на блокировании файлов:
# make a lock
$lockfilename="/tmp/mydaemon.lock";
unless (open (LOCKFILE,">$lockfilename")) {
die "cannot open lock file\n";
}
unless (flock (LOCKFILE,LOCK_EX|LOCK_NB)){
print "my copy is already running\n";
exit(0);
}
# do some work
...
# unlock lock file
close(LOCKFILE);
unlink($lockfilename);
Где взять версию Perl для Windows?
Perl для Windows можно взять на web-сайте Active State Tool Corp. - http://www.activestate.com. Дополнительные пакеты (DBI, GB, MD5, LWP) для Perl под Windows - http://www.activestate.com/PPMpackages/. Полезные советы по работе с Perl под Windows (настройка работы под MS IIS, работа с ADO и ODBC) можно посмотреть на Robin's Perl for Win32 pages.
Как инсталлировать дополнительные модули Perl для Windows?
Вариант I - инсталляция из сети:
В состав поставки ActivePerl входит инструмент для инсталляции пакетов Perl Package Manager (PPM). Для инсталляции необходимого Вам пакета нужно запустить PPM, например, в ДОС сессии, набрав команду
C:\>ppm
после этого можно инсталлировать нужный пакет (модуль):
install <имя_модуля>
(пример: install DBD-CSV)
PPM установит его и пропишет в прилагаемый файл документации.
Вариант II - инсталляция скаченного пакета (модуля):
Вам нужно разархивировать скаченный модуль. После этого найти файл, соответствующий названию пакета и имеющий расширение '.ppd', и набрать команду:
ppm install <файл с расширением .ppd
(пример: ppm install libwin32.ppd)
PPM также позволяет Вам паковать свои собственные модули в PPM-пакеты. Дополнительная информация о том, как это сделать, и о том, где взять необходимые для этого программы nmake, tar и gzip содержится в руководстве по ActivePerl в разделе 'ActivePerl Components' -> 'PPM' -> 'How do I make a PPM package?'
Как сконфигурировать Микрософт IIS 4.0 для работы с ActivePerl?
Частичный перевод раздела ActivePerl FAQ - Web Server Config из руководства, поставляемого вместе с ActivePerl.
Чтобы настроить IIS или PWS 4.0, для запусков сценариев Perl сделайте следующее:
Запустите IIS 4.0 Internet Service Manager.
Выберите нужную Вам папку (уровень) в дереве директорий из которой будут запускаться Ваши приложения. Вы можете выбрать сервер целиком, веб-сервер, или создать виртуальную директорию.
Выбор закладку и нажмите . Запуститься диалог настройки приложений.
Для того, чтобы запускать Perl как приложение CGI, наберите полный путь к Perl.EXE и добавьте в конце %s %s. При запуске Perl сценария в первый %s будет подставляться полный путь на сценарий, а во второй %s -параметры сценария.
Для запуска Perl для ISAPI, наберите полный путь на PerlIS.DLL. Указывать %s %s в этом случае не требуется.
В качестве расширения для приложений (в поле ), укажите .pl или .plx (или то, которое Вы хотите использовать для ваших Perl сценариев).
Настройка теперь завершена. Нажмите <ОК> и нажмите еще раз <ОК> для сохранения изменений.
Закройте IIS 4.0 Internet Service Manager. Так как IIS работает как сервис, Вы должны убедиться в том, что файлы и переменные окружения доступны для него (возможно, Вам придется перезапустить сервис).
Комментарии:
Пункты 4, 5, 6 описывают какое из окон появиться при выборе сервера целиком, веб - сервера и виртуальной директории.
Рекомендую также посмотреть http://www.geocities.com/SiliconValley/Park/8312/perlis.htm - ответы на проблемы с Microsoft Webserver. Там приводятся указания по самостоятельной настройке реестра, описываются различия в работе CGI и ISAPI и т.п.
Как получить значение переменной по имени?
Как получить значение переменной, имя которой записано в другой переменной?
$complex_var = 'qqqq';
$simplex_var = 'zzzz';
$modifier = 'complex';
$result = ${"${modifier}_var"};
Значение $result будет - qqqq
Можно ли скомпилировать из Perl исполняемый файл?
Вы можете воспользоваться программой Perl2Exe. Это утилита для преобразования Perl сценариев в выполняемые файлы, не требующие присутствия интерпретатора языка Perl.
Perl2Exe может сгенерировать модули для Win32 и многих клонов Unix.
Perl2Exe также позволяет Вам создавать не консольные программы, с использованием Tk.
Еще один продукт IndigoSTAR Software - SendMail for Windows(TM) - Windows версия популярной программы Unix Sendmail. Она позволяет отправлять сообщений из командной строки, CGI сценария или BAT-файла.
А как мне проверить соответствие введенного пароля зашифрованному?
Первых два символа пароля соджержат шифровальный ключ. Если взяв их зашифровать проверяемый пароль, то зашифрованные строки должны совпасть. Пример:
if (crypt($entered_passwd,subst($crypted_passwd,0,2))
eq $crypted_passwd) {
# Пароль верен
} else {
# Пароль не верен
}
Как получить статистику по файлу (время создания, изменения и т.п.)?
Как минимим двумя способами!
Вариант 1:
if (-e $filename) { print "Файл существует.\n"; }
if (-z $filename) { print "Файл существует с нулевым размером.\n"; }
if ($size = -s $filename) { print "Файл существует, размер $size.\n"; }
if (-r $filename) { print "Файл может мной читаться.\n"; }
if (-w $filename) { print "Файл может мной исправляться.\n"; }
if (-x $filename) { print "Файл может исполняться.\n"; }
if (-o $filename) { print "Файл мой!\n"; }
if (-f $filename) { print "Файл - это файл.\n"; }
if (-d $filename) { print "Файл - это каталог.\n"; }
if (-l $filename) { print "Файл - это символическая ссылка.\n"; }
if (-p $filename) { print "Файл - это FIFO.\n"; }
if (-S $filename) { print "Файл - это сокет.\n"; }
if (-b $filename) { print "Файл - это блок-ориентированный файл.\n"; }
if (-c $filename) { print "Файл - символьное спец. устройство.\n"; }
if (-t $filename) { print "Файловый манипулятор открыт для терминала.\n"; }
if (-u $filename) { print "У файла установлен бит setuid\n"; }
if (-g $filename) { print "У файла установлен бит setgid\n"; }
if (-k $filename) { print "У файла установлен бит запрета (бит-липучка)\n"; }
if (-T $filename) { print "Файл - текстовый.\n"; }
if (-B $filename) { print "Файл - двоичный.\n"; }
$modific_time = int(-M $filename);
print "возраст файла (с момента изменения) в днях $modific_time.\n";
$access_time = int(-A $filename);
print "дней с последнего чтения файла $access_time.\n";
$ctime = int(-C $filename);
print "возраст изменения файлового дескриптора в днях $ctime";
Вариант 2:
Воспользоваться функцией stat
stat FILEHANDLE
stat EXPR
stat возвращает список из 13-ти элементов. Параметры FILEHANDLE - дескриптор, или EXPR - название. Если EXPR опускается, это равносильно вызову stats `$_.
0 dev device number of filesystem
1 ino inode number
2 mode file mode (type and permissions)
3 nlink number of (hard) links to the file
4 uid numeric user ID of file's owner
5 gid numeric group ID of file's owner
6 rdev the device identifier (special files only)
7 size total size of file, in bytes
8 atime last access time in seconds since the epoch
9 mtime last modify time in seconds since the epoch
10 ctime inode change time (NOT creation time!) in seconds since the epoch
11 blksize preferred block size for file system I/O
12 blocks actual number of blocks allocated
Модуль File::stat обеспечивает удобный, механизма доступа к файлам по именам:
Примеры:
($READ_TIME, $MOD_TIME) = (stat($filename))[8,9];
$READ_TIME = localtime($READ_TIME);
$MOD_TIME = localtime($MOD_TIME);
print "\n последнее обращение к $filename- $READ_TIME";
print "\n последнее изменение $filename- $MOD_TIME";
$mode = (stat($filename))[2];
printf "Права доступа к файлу %04o\n", $mode & 07777;
Как можно стандартизировать (оформить в виде процедуры) получение выборки из БД, чтобы получать набор записей с именованными полями?
Это можно сделать так:
sub QueryArrayOfHashes
my ($DB, $query) = @_;
my ($result,$data_hash,@items,$key,$val,%hash);
$result = $DB->prepare($query);
$result->execute or return;
while ($data_hash=$result->fetchrow_hashref)
%hash=%$data_hash;
push @items,{%hash};
}
$result->finish;
@items;
}
Комментарии:
$data_hash - ссылка на хэш
%$data_hash == %{$data_hash} - получение самого хэша из ссылки
{%hash} = разименованный хэш - чтоб получился массив хэшей, а не просто один массив
@items в данном случае == return @items
Пример использования:
use DBI;
...
$dbh=DBI->connect('DBI:mysql:mysql:localhost', $user, $password,
{RaiseError => 1})
or die "connecting : $DBI::errstr\n";
@res = QueryArrayOfHashes($dbh, "select user, password from user");
for ($i=0; $i<=$#res; $i++) {
print "\n[Record #$i]::\n";
foreach $key (sort keys %{$res[$i]}) {
# запись вида $a[1]{b} эквивалентна $a[1]->{b}
print $key, "\t", $res[$i]{$key}, "\n";
}
}
$dbh->disconnect;
Как мне сделать аутентификацию на Перле, а не средствами веб-сервера?
Для того, чтобы браузер выдал запрос логина и пароля, скрипт должен выдать следующие заголовки:
При этом "что то там" - это имя области авторизации, по правилам для области с одним именем должен всегда срабарывать один и тот же пароль. Проблема заключается в том, что ответ пользователя сидит в заголовке HTTP-запроса, в поле Authorization, которое скрипту через переменные окружения не передаётся. Для сервера Апаче эта проблема решается прописыванием в файле конфигурации следующих строк:
RewriteEngine on
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule ^(.*) - [E=HTTP_CGI_AUTHORIZATION:%1]
Всё что он делает - это добавляет в переменную окружения HTTP_CGI_AUTHORIZATION, в которую пишется содержимое HTTP заголовка Authorization, таким образом означенное поле становится доступным для анализа внутри скрипта. Формат этого поля следующий: "login:password", причём эта строка закодирована в Base64, получить эти составляющие можно так:
use MIME::Base64;
$ENV{HTTP_CGI_AUTHORIZATION} =~ s/basic\s+//i;
($REMOTE_USER,$REMOTE_PASSWD) =
split(/:/,decode_base64($ENV{HTTP_CGI_AUTHORIZATION}));
Как сделать upload картинки через форму?
В случае, если вам не претит воспользоваться модулем CGI, это будет выглядеть примерно так:
use CGI qw/:standard/;
# Код для формы
print "Content-Type: text/html\n\n";
print <file upload