Краткое лирическое отступление насчет CGI



Итак что такое CGI- скрипты и вообще подобные вещи. Начнем с того что ваш браузер (когда вы набрали URL) соединяется по протоколу HTTP с указаным сервером и просит у него нужный файл,примерно так:

GET /~paaa/cgi-bin/guestbbok.cgi HTTP/1.0-Вот это самое главное в запросе

Ну тут дальше идет посылаемая браузером информация о себе и о том что более подробно ему надо.(Например Accept: */*)

Ну и если запрошен простой файл например .html то если если такой файл есть, То сервер отошлет браузеру ответ:

HTTP/1.0 200 Okay
Content-Type: text/html


Далее после пустой строки(она нужна чтоб отделить заголовок от тела) идет информация из самого URL<HTML><BODY>...
Вот в принципе и весь WWW ....ходишь от ссылки к ссылке....
А что если Нужно внести в этот унылый процесс что-нибудь по настоящему интерактивное , динамическое,прекрасное и великолепное....? Чтож есть ответ и на этот вопрос. Просто что если в запрашиваемом URL указать спецыальную программу (CGI,программа Common Gateway Inteface - Общего Шлюзового Интерфейса) и то что эта прога выдаст то и отправить браузеру....Сервер запускает .cgi программу и она например обработав данные формы заносит вас куда-нибудь в свою базу данных,а вам сообщит что вы большой молодец :)
Ну надеюсь я вас заинтриговал......?

Итак ...приступим...

Краткие сведения о том что надо знать чтоб писать CGI скрипты: Ну вопервых надо знать что такое интернет и как он работает (а вы знаете? ;))) ) Ну и чуть-чуть умения прграмировать(это самое главное)
Давайте вместе писанем какой нибудь простенький скриптик а потом я вам расскажу где сдесь собака порылась....
Ну сначала в своем домашнем каталоге создайте директорию cgi-bin:

cd public_html
mkdir cgi-bin
chmod 0777 cgi-bin

Последняя строчка будет очень важна.
Возьмите редактор и наберите:

#!/usr/bin/perl

#first.cgi

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

print "<HTML><BODY>";

print "<H1>Hello you!!!</H1>";

print "</BODY></HTML>";


Сохраните его в директории cgi-bin под именем first.cgi .Ну как сохранили?
А теперь сделайте его исполняемым(ведь это программа):

chmod +x first.cgi

Ну вот,подходим к торжественному моменту.... наберите в строке браузера http://www.uic.nnov.ru/~твой_логин/cgi-bin/first.cgi
и посмотрите чо будет. Будет одно из двух ,либо скрипт заработает и вы увидите сгенерированую им страничку (поздравляю,в нашем полку прибыло!) либо Internal Server Error -тогда не расстраивайтесь,вы что-то сделали не так. Вам тогда пригодится пособие по ловле блох. Ну вопервых проверку синтаксиса можно осуществить следующим образом:

Perl -с first.cgi

Perl вам сразу выдаст либо сообщения об ошибках(ну бывает,точку с запятой пропустили, скобочки или кавычки забыли закрыть...) это сразу по ходу дела поправимо.
Более грубая с логической точки зрения это пропустить вывод пустой строки, которая отделяет заголовок от тела:

print "Content-Type: text/html\n\n"; #Все Правильно

print "Content-Type: text/html\n"; #ОШИБКА!!!


Разберем скрипт:
Первая строка #!/usr/bin/perl Просто указывает где в системе расположен Perl. Вторая это просто коментарий -вы можете тыкать чо угодно после знака #
Затем идет print "Content-Type: text/html\n\n"; Это заголовок указывающий тип содержимого все что скрипт печатает в свой стандартный вывод STDOUT идет на обработку к серверу. Пустая строка отделяет заголовок от тела,которое в нашем случае представляет собой
<HTML><BODY>
<H1>Hello you!!!</H1>
</BODY></HTML>
Сервер обработает ответ скрипта и на базе него сформирует и пошлет браузеру ответ.(Сервер обычно не изменяет тела сообщения,он только дополняет заголовок нужными для протокола HTTP полями)

Ну вот азы уже освоены,все не так трудно и удручающе как могло показаться на первый раз
Вы теперь можете сами потренироваться в написании таких вот простеньких скриптов чтоб набить руку.

Переменные среды CGI

Предыдущий скрипт не содержал ничего особенно замечательного,так просто вываливал HTMLый текст который благополучно и отбражался на екране браузера.Но По настоящему мощь придает CGI возможность обработки параметров,которые переданы скрипту.например вы можете набрать
http://www.somehost.ru/somedir/cgi-bin/my_cgi.cgi?param=value
то есть вы хотите чтоб скрипт my_cgi.cgi обработал для вас параметер param со значением value (ну это например) или когда вы заполнили запрос в форме (в например yahoo или altavista).Ну это с точки зрения пользователя... А на сервере при запуске CGI-скрипта сервер формирует среду окружения в которой скрипт может найти всю доступную информацию о HTTP-соединении и о запросе.
Вот эти переменные:

REQUEST_METHOD

Это одно из самых главных поле используемое для определения метода запроса HTTP Протокол HTTP использует методы GET и POST для запроса к серверу.Они отличаются тем что при методе GET запрос является как-бы частью URL т.е. http://www..../myscript.cgi?request а при методе POST данные передаются в теле HTTP-запроса (при GET тело запроса пусто) и следовательно для CGI тоже есть различие при GET запрос идет в переменную QUERY_STRING а при POST подается на STDIN скрипта.
Пример:REQUEST_METHOD=GET

QUERY_STRING

Это строка запроса при методе GET. Вам всем известно что запрос из формы кодируется браузером поскольку не все символы разрешены в URL некоторые имеют специальное назначение. Теперь о методе urlencode: неплохо бы чисто формально напомнить,что все пробелы заменяются в URL на знак '+', а все специальные и непечатные символы на последовательность %hh ,где hh-шестнадцатиричный код символа,разделитель полей формы знак '&',так что при обработке форм надо произвести декодирование.
Пример:QUERY_STRING= name=quake+doomer&age=20&hobby=games

CONTENT_LENGTH

Длина в байтах тела запроса.При методе запроса POST необходимо считать со стандартного входа STDIN CONTENT_LENGTH байт,а потом производить их обработку.Обычно методом POST пользуются для передачи форм,содержащих потенциально большие области ввода текста TEXTAREA.При этом методе нет никаких ограничений,а при методе GET существуют ограничения на длину URL .
Пример:CONTENT_LENGTH=31

CONTENT_TYPE

Тип тела запроса(для форм кодированых выше указаным образом он application/x-www-form-urlencoded)

GATEWAY_INTERFACE

Версия протокола CGI.
Пример:GATEWAY_INTERFACE=CGI/1.1

REMOTE_ADDR

IP-Адрес удаленого хоста,делающего данный запрос.
Пример:REMOTE_ADDR=139.142.24.157

REMOTE_HOST

Если запрашивающий хост имеет доменное имя,то эта переменная содержит его, в противном случае -тот же самый IP-адресс что и REMOTE_ADDR
Пример:REMOTE_HOST=idsoftware.com

SCRIPT_NAME

Имя скрипта,исполизованое в запросе.Для получения реального пути на сервере используйте SCRIPT_FILENAME
Пример:SCRIPT_NAME=/~paaa/guestbook.cgi

SCRIPT_FILENAME

Имя файла скрипта на сервере.
Пример:SCRIPT_FILENAME=/home/p/paaa/public_html/cgi-bin/guestbook.cgi

SERVER_NAME

Имя серера ,чаще всего доменное как www.microsoft.com ,но в редких случаях за неимением такового может быть IP-адресом как 157.151.74.254
Пример:SERVER_NAME=www.uic.nnov.ru

SERVER_PORT

TCP-Порт сервера используюшийся для соединения .По умолчаниию HTTP-порт 80, хотя может быть в некоторых случаях другим.
Пример:SERVER_PORT=80

SERVER_PROTOCOL

Версия протокола сервера.
Пример:SERVER_PROTOCOL=HTTP/1.1

SERVER_SOFTWARE

Програмное обеспечение сервера.
Пример:Apache/1.0

AUTH_TYPE, REMOTE_USER

Эти переменные определены в том случае,когда запрошеный ресурс требует аутентификации пользователя.

Переменные заголовка HTTP-запроса.
За исключением тех строк из заголовка HTTP-запроса которые были включены в другие переменные,сервер приделывает строкам префикс HTTP_ и заменяет знаки '-' на '_':
HTTP_ACCEPT

Давая запрос на сервер браузер обычно расчитывает получить информацию определеного формата,и для этого он в заголовке запроса указывает поле Accept:,Отсюда скрипту поступает cписок тех MIME,которые браузер готов принять в качестве ответа от сервера.
Пример:HTTP_ACCEPT=text/html,text/plain,image/gif

HTTP_USER_AGENT

Браузер обычно посылает на сервер и информацию о себе,чтоб базируясь на знании особеностей и недостатков конкретных браузеров CGI-скрипт мог выдать информацию с учетом этого. Например,разные браузеры могут поддерживать или не поддерживать какие-то HTMLые тэги.
Пример:HTTP_USER_AGENT=Mozila/2.01 Gold(Win95;I)

 

Ну,начнем применять на практике усвоеные уроки.

#!/usr/bin/perl

#vars.cgi

sub urldecode{ #очень полезная функция декодирования

 local($val)=@_; #запроса,будет почти в каждой вашей CGI-программе

 $val=~s/\+/ /g;

 $val=~s/%([0-9A-H]{2})/pack('C',hex($1))/ge;

 return $val;

 }

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

print "<HTML><HEAD><TITLE>CGI-Variables</TITLE></HEAD>\n";

print "<BODY>\n";

print "Enter here something:<ISINDEX><BR>\n";

print "Your request is:$ENV{'REQUEST_STRING'}<BR>\n";

print "Decoded request is:urldecode($ENV{'REQUEST_STRING'})<BR>\n";

print "<HR>\n";

print "Variables:<BR>\n";

print "<I><B>REQUEST_METHOD</B></I>=$ENV{'REQUEST_METHOD'}<BR>\n";

print "<I><B>QUERY_STRING</B></I>=$ENV{'QUERY_STRING'}<BR>\n";

print "<I><B>CONTENT_LENGTH</B></I>=$ENV{'CONTENT_LENGTH'}<BR>\n";

print "<I><B>CONTENT_TYPE</B></I>=$ENV{'CONTENT_TYPE'}<BR>\n";

print "<I><B>GATEWAY_INTERFACE</B></I>=$ENV{'GATEWAY_INTERFACE'}<BR>\n";

print "<I><B>REMOTE_ADDR</B></I>=$ENV{'REMOTE_ADDR'}<BR>\n";

print "<I><B>REMOTE_HOST</B></I>=$ENV{'REMOTE_HOST'}<BR>\n";

print "<I><B>SCRIPT_NAME</B></I>=$ENV{'SCRIPT_NAME'}<BR>\n";

print "<I><B>SCRIPT_FILENAME</B></I>=$ENV{'SCRIPT_FILENAME'}<BR>\n";

print "<I><B>SERVER_NAME</B></I>=$ENV{'SERVER_NAME'}<BR>\n";

print "<I><B>SERVER_PORT</B></I>=$ENV{'SERVER_PORT'}<BR>\n";

print "<I><B>SERVER_PROTOCOL</B></I>=$ENV{'SERVER_PROTOCOL'}<BR>\n";

print "<I><B>SERVER_SOFTWARE</B></I>=$ENV{'SERVER_SOFTWARE'}<BR>\n";

print "<I><B>HTTP_ACCEPT</B></I>=$ENV{'HTTP_ACCEPT'}<BR>\n";

print "<I><B>HTTP_USER_AGENT</B></I>=$ENV{'HTTP_USER_AGENT'}<BR>\n";

print "<HR>\n";

print "All enviroment:<BR>\n";

foreach $env_var (keys %ENV){

 print "<I>$env_var=$ENV{$env_var}</I><BR>\n";

 }

print "</BODY></HTML>\n";

Так как все ваши .cgi -файлы должны быть исполняемыми то чтоб облегчить себе жизнь заведите себе в директории cgi-bin командный файл mkcgi ,содержащий

chmod +x *.cgi

и сделайте его в свою очередь исполняемым chmod +x mkcgi -он сильно упростит вам жизнь.
Ну а теперь запускайте скрипт......
Изучив информацию,выдаваемую данным скриптом вы сможете лучше ориентироваться в переменных окружения CGI.

Прекрасный язык Perl

Вы наверное обратили свое внимание что CGI скрипты пишутся обычно на языке Perl (Practical Extraction and Report Language)- очень удобном языке,впитавшем из других все лучшие черты.Может у вас возникнуть сомнение :Ну вот!Изучать новый язык программирования!? Спешу вас успокоить,изучение Perl не будет в тягость (я сужу по своему опыту!). Вы даже сами не заметите как выучите его.Если вы хоть когда-нибудь программировали скажем на C и использовали утилиту grep для поиска регулярных выражений в тексте,то вам будет еще легче.Мое изучение Perl началось с того что я скачал Perl под Windows (фирмы ActiveWare) и изучения той HTMLой документации которая к нему прилагалась хватило чтоб этот язык стал моим любимым....
Все в нем сделано для удобства программиста (в отличии например от Java;( )
Начнем с переменных,они в Perl бывают 3х типов скаларные,списковые(массивы) и хэши(ассоциативные массивы). Для указания компилятору(да и для немалого удобства программиста) перед именем скалярной переменной стоит знак '$' перед массивом '@',перед хешем '%'. т.е. например $scalar_var,@array_var,%hash_var Скалярные переменные могут быть как числовые так и строковые,но это не надо указывать Perl сам по контексту в зависимости от операций может привести одно к другому.
Например: "123"+"4" будет 127 (или "127") так как операция '+' действует над числами а вот если применить операцию конкатенации строк '.' то строковое "test" . 1 будет "test1"
Ну а вот операции над скалярными переменными:

Операцыи Описание Пример
+ - * / % Арифметические print 2*7+4/(8%3); print int(127/15); #целая часть
** Возведение в степень print 2**16;
++ -- Инкремент-декремент $i++;
& | ^ ~ << >> Побитовые $x=3;$y=4; print $x|$y; print $x&$y;
== != < > <= >= <=> Числовые операции сравнения if($x==9){print "Ok!";}
eq ne lt gt le ge cmp стрковые операции сравнения if($game eq 'doom'){print "You are doomer!\n";}
|| && ! Логические if(($x==9)||($game eq 'doom')){print "hello you!\n";}
?: Условный оператор $x=($game eq 'quake'?9:8);
, Последовательное вычисление $x=10,$y=20;
. Конкатенация $x='http://'.'www.uic.nnov.ru';
x Повторение $x='1234'x5; #$x='12341234123412341234'
=~ Сопоставление с образцом if($url=~/http/){print "HTTP";}
!~ То же но с отрицанием if($url!~/http/){print "No HTTP";}
= += -= *= /= %= **= |= &= ^= ~= <<= >>= .= x= Присваивание $x+=$y;
     

Пусь это будет вам справочником ,да кстати насчет строк,вы заметили,что они могут быть в двойных и одинарных кавычках, разница между ними состоит в том ,что в одинарных не осуществляется подстановка переменных, а в двойных осущестляется, Например:

$x='qwerty';

print 'my var is $x'; #выведет my var is $x

print "my var is $x"; #выведет my var is qwerty

Списки: Спискочные переменные начинаются с символа '@' конструируются следующим образом

@List1=(1,2,5,70);

@List2=(12,23,@List1); #12,23,1,2,5,70

@Rgb=($r,$g,$b);

Также можно список использовать как lvalue:

@List=(1,2,3..8,15);

($x,$y,$z)=@List;   #$x=1,$y=2,$z=3

($x,$y,$z,@list2)=@List; #$x=1,$y=2,$z=3,@list2=(4,5,6,7,8,15);

($r,$g,$b)=@Rgb;

Можно обращаться к нескольким,выбраным элементам массива(срезу массива):

@list=(1..10);

@list[2,3,5,9]=(100,200,300,400); #@list=(1,100,200,4,300,6,7,8,400,10)

@list[1,10]=@list[10,1];#меняет местами элементы

Обратится к скаларному значению -элементу массива можно $имя_массива[индекс], сдесь обратите внимание на знак '$'- мы ведь обращаемся к скаляру-элементу.
Теперь немного о хешах:
хеш это такой массив который состоит из пар ключ-значение, весь хеш обозначается %хеш ,к отдельным элементам доступ $хеш{скалярное выражение} конструируется хеш так:

$my_hash{1}="doom";

$my_hash{'quake'}="www.idsoftware.com";

$my_hash{1+2}=100;

Хеш может быть также сконструирован из массива с четным числом элементов где пары превращаются в ключ-значение

%hash=(1,20,2,100);#аналогично $hash{1}=20;$hash{2}=100;

удаление из хеша -операция delete:

delete $hash{1};

есть функции выдающие ключи и значения соответственно.

%hash=(1,20,2,100,3,'doom');

@k=keys %hash; #@k=(1,2,3);

@v=values %hash;#@v=(20,100,'doom');

Операторы:
Набор операторов в Perl Очень широк,многие из них прямые аналоги имеющихся в других языках,например if,for,while;но есть и значительные улучшения имеюшихся и конечно новые...
Тот же самый оператор if имеет две формы (как когда удобнее):

if(условие)оператор;

оператор if условие;

В пару к оператору if имеется оператор unless : означающий if с отрицанием:

unless(($method eq 'GET')||($method eq 'POST')){print "Unsupported method";}

print "Ok" unless $x < $y;

Также в пару while существует until
синтаксис оператора for полностью аналогичен C:

for($i=0;$i<10;$i++){

 print $i;

 }

новшеством(и приятным) является foreach позволяющий пройтись по всем элементам массива,присваивая по очереди его элементы какой-то переменной, его синтаксис такой:

foreach $переменная (@массив){

 блок операторов;

 }

Или

foreach (@массив){

 операторы;

 }

Последний пример особенно важен для упрощения вашего тяжкого труда програмиста и демонтстрирует интересную особенность Perl-переменную по умолчанию $_: в оргомном количестве операторов и функций при опускании аргумента она подразумевается по умолчанию. Она также по умолчанию сопоставляется с регулярным выражением:

Следующий пример

@Data=<STDIN>;

foreach(@Data){

 chomp;

 print if /^From:/;

 }

аналогичен такому:

@Data=<STDIN>;

foreach $_ (@Data){

 chomp($_);

 print $_ if $_ =~ /^From:/;

как видите затраты труда значительно сокращаются,благодаря этому маленькому трюку. Регулярные выражения.
регулярное выражение записывается между двух слэшей /рег_выр/

if(/abc/){

 print '$_ содержит abc\n';

 }

это самый простой пример применения регулярного выражения а теперь посложнее вот тут в табличке (из того что я помню наизусть):

Символ Значение Пример применения
. Соответствует любому символу print if /ab.c/;
[мн-во симв] Соответствует любому символу из данного мн-ва /[abc]d/;#соответствует ad,bd,cd
[^мн-во] Отрицание мн-ва символов /[^xyz]/;#
(....) Группировка элементов(и также запоминание в переменных $1 $2 $3 ...) /(xyz)*/ /([abc].[^xy]qwerty)/
(..|..|..) Одна из альтернатив  
* повторение образца 0 или более раз /.*/;#соответствует всему
? Повторение 0 или 1 раз /(http:\/\/)?.*\.cgi/
+ Повторение 1 или более раз  
{n,m} повторение от n до m раз  
{n} повторение точно n раз  
{n,} повторение n и более раз  
Спец символы:    
\t \r \n ... Управляющие символы:табуляции,возврат каретки,перевод строки.....  
\d Соответствует цифре,Аналог [0-9]  
\D Соответствует нецифровому симсволу,аналог[^0-9]  
\w Соответствует букве  
\W Соответствует небуквеному символу  
\s Соответствует пробельным символам(пробелы,табуляции,новые строки..)  
\S Соответствует непробельному символу  
\b Соответствует границе слова $test1="this is test"; $test2="wise"; if($test1=~/\bis\b/){print "1";}#соответствует if($test2=~/\bis\b/){print "2";}#нет
\B Соответствует не границе слова /\Bis\B/ соответсвует 'wise' но не 'is'

Для того чтоб поместить в регулярное выражение любой специальный символ,поставьте реред ним обратный слэш Заставить Perl игнорировать регистр можно поставив i после регулярного выражения

print "Are you sure?:";

$answer=<STDIN>;

if($answer=~/Y/i){

Че-нибудь сделаем...

 }


Полезные функции.
В Perl очень много различных функций ,как говорится на все случаи жизни,все о них я конечно не опишу,но обо многих. Начну с тех,которые больше относятся к операторам. Операция замены s/рег.выражение/строка/ игнорировать регистр - опция i глобальная(по всей строке) замена -опция g; Пример:

 $x="This is test";

 $x=~s/ /_/g;

 print $x; #This_is_test

Очень полезная опция у s/// e -она означает что вторая строка не строка а выражение, результат которого и будет подставлен. Например,у вас есть файл в котором все записи о возрасте через год надо менять

 open OLD,"oldfile.txt" || die "Cannot open oldfile.txt $!\n";

 open NEW,">newfile.txt" || die "Cannot open newfile.txt $!\n";

Foreach(

){

s/(\d+)(\s+год)/($1+1).$2/gie;

s/(\d+)(\s+лет)/($1+1).$2/gie;

print NEW $_;

}

 close NEW;

 close OLD;

или более показательным примером послужит функция urldecode,которая будет встречатся в каждой вашей программе,обрабатывающей формы:

sub urldecode{

 local($val)=@_;

 $val=~s/\+/ /g;

 $val=~s/%([0-9A-H]{2})/pack('C',hex($1))/ge;

 return $val;

 }

Также важным удобством в Perl являются операции для работы с файлами для выполнения схожих функций в других языках приходиться проделывать огромную массу работы. Аргументами могут быть как Файловые переменные,так и строки,представляющие имя файла.

Операция Описание Пример использоввания
-r Доступен для чтения unless(-r "myfile"){print "Cannot read myfile\n";}
-w Доступен для записи  
-x Для исполнения  
-o Принадлежит пользователю if(-o "index.htm"){chmod 0777,"index.htm";}
-R Доступен для чтения реальным пользователем,а не только "эффективным". Имеет значения для set-uid -скриптов if(-r FILE){unless(-R FILE){die "Its not allowed to read this\n";}}
-W Доступен для записи реальным пользователем  
-X Доступен для исполнения реальным пользователем  
-O Принадлежит реальному пользователю  
-e Файл или каталог Существует unless(-e $htmlfile){ open HTML,">$htmlfile"; print HTMLFILE "<HTML><BODY></BODY></HTML>"; close HTMLFILE; }
-z Существует,но имеет нулевую длину if(-z 'tmpfile'){unlink 'tmpfile';}
-s Размер файла в байтах system "rar m -m5 archive.rar $myfile" if -s $myfile > 1000;
-f Файл существует и является простым файлом  
-d Файл существует и является каталогом if(-d 'public_html'){chdir 'public_html';}
-l Символической ссылкой  
-p Каналом FIFO  
-u Имеет бит установки пользователя  
-g Имеет бит установки группы  
-k Установлен sticky-бит  
-t Является терминальным устройством  
-M Время с последнего изменения (в днях) while(defiled($file=glob('*'))){ if(-M $file >= 7.0){ unlink($file);#удаляем слишком старые файлы } }
-A Время последнего доступа(в днях) if(-A "$ENV{'HOME'}/public_html/index.html" < -A "$ENV{'HOME'}/.last"){print "Кто-то ходил на твою домашнюю страничку пока тебя не было!!!\n";}
-C Время последнего обновления файлового индекса(в днях)  
     

Еще есть и другие
функция open открывает файл

open ФАЙЛОВАЯ_ПЕРЕМЕННАЯ,"имя файла"; #открыть файл для чтения

open ФАЙЛОВАЯ_ПЕРЕМЕННАЯ,">имя файла"; #для записи

open ФАЙЛОВАЯ_ПЕРЕМЕННАЯ,">>имя файла";#для записи в конец

open ФАЙЛОВАЯ_ПЕРЕМЕННАЯ,"+<имя файла";#для чтения и записи

open ФАЙЛОВАЯ_ПЕРЕМЕННАЯ,"|комманда"; #направить информацию на вход программы

open ФАЙЛОВАЯ_ПЕРЕМЕННАЯ,"комманда|"; #считать информацию с выхода программы

open ФАЙЛОВАЯ_ПЕРЕМЕННАЯ,"|комманда|"; #и то и другое вместе

Что какается открытия файлов,то вам как програмистам все очевидно, но с коммандами тоже все здорово,что пояснит хороший пример(из практики):

open MAIL,"|mail paaa@uic.nnov.ru";#Пошлем информацию по почте

print MAIL "Hello\n";

print MAIL "...\n";

print MAIL "...\n";

close MAIL;

когда вы открыли файл вы можете считать из него строку в скалярную переменную Вот так:$str=<FILE>
избавиться от символа новой строки на конце поможет функция chomp, ведь этот символ может помешаться например в имени файла или при выводе на экран

print "Введите имя файла:";

$fname=<STDIN>;

chomp($fname);

open F,$fname || die "Cannot open $fname $!\n";

.....

Если также подставить списочную переменную,то получим список строк файла от текущей строки и до конца

print "Что искать:";

$search=<STDIN>;

chomp($search);

@L=<F>;

foreach(@L){

 print if /$search/;

 }

а можно и так:

print "Что искать:";

$search=<STDIN>;

chomp($search);

foreach(<F>){

 print if /$search/;

 }

бинарный файл можно читать и писать функциями sysread и syswrite:
sysread ФАЙЛОВАЯ_ПЕРЕМЕННАЯ,$скалярная_перемменая,сколько_байт
syswrite ФАЙЛОВАЯ_ПЕРЕМЕННАЯ,$скалярная_перемменая,сколько_байт
функции split и join: @Список=split /рег.выр/,$скаляр;
$скаляр=join строка,@Список;

#Разбить строку слов,разделенных пробелами в список вы можете

@WordList=split / /,$String;

#После обработки снова обьединить

$String=join ' ',@WordList;

Встроеные функции Perl можно вызывать со скобками или без (как вам удобно), скобки программисты указывают или для красоты,или чаще,что устранить возможную неоднозначность в выраженнии:

printf "x=%d",$x;

printf ("x=%d",$x);#аналогично

Надеюсь что я вас позабавил примерами функций ;).
Примеры применения Perl для различных нужд...
Следующая программа переводит текстовый файл в формат HTML (вспомните сколько хлопот вам доставит отлов во всем файле '<', '>' и '&' чтоб заменить их на &tl; , &gt;и &amp; а как неплохо чтоб автоматически все http://www.... превратились в <A href="http://www...." >http://www....</A>)

#!/usr/bin/perl

#txt2html

die "Usage: txt2html Infile OutFile\n" unless(@ARGV);

open IN,"$ARGV[0]" || die "Cannot open $ARGV[0] $! \n";

open OUT,">$ARGV[1]" || die "Cannot open $ARGV[1] $! \n";

while(<IN>){

 s/&/&amp;/g;

 s/</&lt;/g;

 s/>/&gt;/g;

 s/\n/<BR>\n/g;

 s/(http:\/\/\S+)/<A href="$1">$1<\/A>/g;

 print OUT $_;

 }

close IN;

close OUT;

Заголовки запросов и ответов


Даже если вы и знаете кое-что о HTTP все равно не лишне будет вспомнить о том как это все работает тем более на эту информацию придется ориентироваться при написании CGI скриптов.
Этапы соедирения.
Первый этап это когда HTTP -клиент(браузер) соединяется с сервером.для этого он использует протокол TCP/IP соединение происходит к известному клиенту TCP-порту (80 -номер порта HTTP) (другие сервисы сидят на других портах ,например FTP и SMTP на 21 и 25)
Вторым этапом идет запрос клиента:клиент передает заголовок запроса и возможно(в зависимости от метода) тело сообщения запроса.В заголовке обязательно указывается метод ,URI,и версия HTTP,и может быть еще несколько необязательных полей
Третий этап -ответ сервера,который опять таки состоит из заголовка,в котором сервер указывает версию HTTP и код статуса, который может говорить о успешном или неуспешном результате и его причинах.Далее идет тело ответа.
Четвертым этапом происходит разрыв TCP/IP соединения.
HTTP -запрос.
Запрос состоит из Строки запроса(она обязательна) и остальных полей. Синтаксис строки :МЕТОД <SP> URI <SP> HTTP/версия <CRLF>
где <SP> -пробел ,<CRLF> -переход на новую строку
Методы HTTP.
GET
Самый часто применяемый метод,в протоколе HTTP/0.9 был единственным методом,и применяется для извлечения информации по заданому URI Может быть условным если в заголовке указано поле If-Modified-Since:

HEAD
Почти идентичен GET но отличается тем что сервер не возвращает тело обьекта а только его заголовок (метаинформацию) программы могут применять его для проверки гиперссылок на правильность,доступность и изменения.

POST
передает данные для обработки их программой ,указаной в URIсдесь обязательно указывается поле Content-Length:

Сушествуют и другие ,реже применяемые методы,например PUT -для сохранения передавемых данных в указаном URI и DELETE для удаления ресурса.

Поля заголовка запроса.
После строки запроса идут поля заголовка запроса. Поля общего(general-header) заголовка (он общий как для запросов так и для ответов):
Date:
Указывает дату запроса,например:
Date: Sun, 20 Nov 1994 08:12:31 GMT

MIME-version:
Указывает версию MIME (по умолчанию 1.0)
MIME-version: 1.0

Pragma:
Содержит указания для таких промежуточных агентов как прокси и шлюзы,
Pragma: no-cache


Поля относящиеся к запросу(Request-Header):
Authorization:
Содержит информацию аутентификации
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

From:
Браузер может посылать адрес пользователя серверу
From: quake@doom.ru

If-Modified-Since:
используется при методе GET ресурс возвращается ,если он был изменен с указаного момента, может использоваться при кешировании.
If-Modified-Since:Mon 15 Jul 1997 00:15:24 GMT

Referer:
Содержит URL предшествующего ресурса.
Referer: http://www.uic.nnov.ru/~paaa/index.html

User-Agent:
Програмное обеспечение клиента.
User-Agent: Mozilla/3.0

Заголовок информации сообщения (Entity-Header) применяется как в запросах так и в ответах (при этом некоторые поля только в ответах):
Allow: (в ответе сервера)
Список методов,поддерживаемых ресурсом.
Allow: GET, HEAD

Content-Encoding:
идентифицирует метод кодировки,которым был закодирован ресурс
Content-Encoding: x-gzip

Content-Length:
Длина тела сообщения
Content-Length: 102

Content-Type:
Содержит тип ресурса(MIME),для текстовых еще и кодировку символов(необязательно)
Content-Type: text/html; charset=windows-1251

Expires: (в ответе сервера)
Дата окончания действия ресурса,применяется в кешировании для запрета кеширования устаревших ресурсов (в ответе)
Expires: Tue, 24 Sep 1998 23:00:15 GMT

Last-Modified: (в ответе сервера)
Время последнего обновления ресурса
Last-Modified: Tue, 23 sep 1998 13:48:40 GMT

Другие поля:
Поля Accept: указывают серверу выдавать только указаные форматы данных,которые клиент может распознать.
Accept: text/html
Accept: text/plain
Accept: image/gif
Примеры запросов:

Простейший запрос:

GET /index.html HTTP/1.0

Посложнее:


Дата добавления: 2018-04-04; просмотров: 412; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!