Отладка cgi скриптов на perl


Содержание

Как я могу отлаживать CGI Perl script?

Я унаследовал устаревший Perl script со старого сервера, который удаляется. script должен быть реализован на новом сервере. Я получил его на новом сервере.

script довольно прост; он подключается через expect и ssh к сетевым устройствам и собирает данные. Для целей отладки я работаю только с частью, которая собирает список интерфейсов с устройства.

script на новом сервере всегда показывает мне страницу в течение примерно 5 секунд после ее перезагрузки. Редко он включает в себя список интерфейсов с удаленного устройства. Чаще всего он содержит все элементы HTML, кроме списка интерфейсов.

Теперь, на старом сервере, иногда script потребуется 20 секунд для вывода данных. Это было хорошо.

На основании этого кажется, что apache на новом сервере отображает данные до того, как Perl script закончил возвращать свои данные, хотя это, безусловно, может быть неверным.

Дополнительная информация: К сожалению, я не могу опубликовать какую-либо политику работы с кодом. Тем не менее, я уверен, что это не проблема с ожиданием. Части ожидания записываются как expect() или die (‘error msg’), и я не вижу сообщений об ошибках. Однако, если я устанавливаю время ожидания ожидания равным 0, я вижу сообщения об ошибках.

Значение ожидания ожидания ожидания, используемое в script, обычно составляет 20 секунд. но, как я уже упоминал выше, apache отображает статическое содержимое из script примерно через 5 секунд, а 95% времени не отображается содержимое, которое следует извлечь из ожидаемого. Кроме того, script записывает ожидаемое содержимое в файл на диске — даже если страница не отображает его.

CGI, Программирование CGI-скриптов на Перле

Владивостокский государственный университет экономики и сервиса

Максим Мамаев

Технологии Интернет
Лабораторный практикум

Тема 6. CGI

Литература и ссылки

  • Shishir Gundavaram «CGI Programming on the World Wide Web» — O’Reilly, First Edition, March 1996; ISBN: 1-56592-168-2, 433 pages. .
  • S. Spainhour, V. Quercia «WebMaster in a Nutshell» — O’Reilly, First Edition, October 1996; ISBN: 1-56592-229-8, 356 pages. .
  • Оригинальный сайт проекта Apache
  • Сайт проекта Русский Апач
  • Библиотека Афины, документация по Apache.
  • Библиотека Афины, стандарты RFC по HTTP.
  • Оригинальный сайт языка Perl
  • Библиотека CGI.pm для Perl (документация).

Используемое ПО:

  • Unix (Solaris 2.x),
  • Russian Apache (Apache 1.3.6PL28.16) (распространяется свободно).
  • Язык программирования Perl v. 5.005_03, библиотека CGI.pm и сопутствующие библиотеки (распространяется свободно).
  • Модуль mod_perl v. 1.21 (распространяется свободно).

Интерфейс CGI

Клиент может запросить у веб-сервера как документ-файл с диска, так и документ, динамически формируемый некоторой внешней программой (как правило — в зависимости от данных, предоставленных пользователем при заполнении формы). Интерфейс CGI представляет собой спецификацию взаимодействия веб-сервера и внешней программы, которую веб-сервер запускает для обработки запроса. (Внешняя программа, вне зависимости от своей природы, часто называется CGI-скриптом.)

CGI определяет каким образом данные, предоставленные клиентом в запросе, передаются программе, как программа возвращает сгенерированный HTML-контент серверу, и какие переменные окружения устанавливаются сервером при запуске программы. Переменные окружения несут дополнительную информацию о сервере и запросе (например, тип сервера, IP-адрес клиента и др.).

Данные из заполненной клиентом HTML-формы могут передаваться на сервер двумя методами: GET и POST, это определяется параметром method соответствующего тэга . В первом случае (GET) данные присоединяются после вопросительного знака в конец URL, указанной в параметре action, во втором случае — передаются в теле запроса — в секции, предназначенной для данных (следует после всех заголовокв и пустой строки). В обоих случаях данные кодируются одинаково — см. след. пункт.

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

CGI-программа выдает содержимое ответа (как правило, HTML-контент) на свой стандартный вывод, который перехватывается веб-сервером с тем, чтобы отослать эти данные клиенту. Предварительно CGI-программа должна напечатать заголовок «Content-Type» и отделить его от данных пустой строкой. Например, вывод CGI-программы, генерирующей HTML, может выглядеть следующим образом:

Конфигурирование сервера Apache для исполнения CGI-скриптов

Для того, чтобы Apache воспринимал все файлы, находящиеся в некотором каталоге как CGI-скрипты, нужно использовать директиву Это означает, что для обработки запроса URL вида http://your.server.com/cgi-bin/dir/script будет взят не файл script из каталога DocumentRoot/cgi-bin/dir/, а запущена программа /usr/local/www/cgi-bin/dir/script.

Для смешанного хранения файлов, подлежащих просмотру, и CGI-скриптов в одном каталоге внутри дерева DocumentRoot следует присвоить CGI-скриптам одинаковые расширения (например, «.cgi») и указать серверу, что интерпретировать такие файлы следует как CGI-скрипты: Директива AddHandler может быть использована в любом контексте конфигурации Apache.

Структура URL и кодирование данных запроса

Для работы CGI-программ важное значение имеют части URL, называемые PATH_INFO и QUERY_STRING. Рассмотрим запрос с URL вида

Используя директиву ScriptAlias, приведенную в предыдущем пункте, сервер определяет что произошло обращение к CGI-программе и для поиска этой программы заменяет начальное /cgi-bin/ на /usr/local/www/cgi-bin/. Следуя запрошенному URL, сервер обнаруживает в этом каталоге подкаталог dir, однако подкаталога prog в каталоге /usr/local/www/cgi-bin/dir не обнаружено. В таком случае сервер предполагает, что prog — имя CGI-программы, подлежащей выполнению. Если программа /usr/local/www/cgi-bin/dir/prog не найдена или не может быть исполнена, сервер возвращает клиенту ошибку 403, 404 или 500. В противном случае программа prog запускается, а оставшаяся часть пути из URL — /a/b — передается программе prog в переменной окружения PATH_INFO. Таким способом можно передать в CGI-программу дополнительные параметры.

Все, что находится после вопросительного знака — A=1&B=qwerty — передается программе prog в переменной окружения QUERY_STRING. Это могут быть данные из заполненной пользователем формы, отправленные на сервер методом GET, либо какая-то другая информация (сервер не делает никаких предположений об интерпретации данных в QUERY_STRING, это задача вызываемой программы).

Данные из полей формы, заполненной пользователем — независимо от метода (POST или GET), которым они пересылаются на сервер — кодируются следующим образом:

Пары имя-значение разделяются амперсандом. Алфавитно-цифровые символы и некоторые знаки препинания, не имеющие специального значения (тире, подчеркивание) передаются как есть. Остальные символы кодируются в виде «%NM«, где NM — двузначный шестнадцатеричный код символа. Пробел может передаваться как «%20» или как символ «+». Кириллические символы также должны кодироваться указанным способом. Кодировка производится броузером при отправке полей заполненной формы.

Например: означает, что в поле birthday пользователь внес «11/05/73», а в поле name — «John Smith».

Декодирование данных формы является задачей CGI-программы.

При пересылке данных формы, закодированных вышеописанным способом, методом POST клиент должен установить заголовок запроса Content-Type следующим образом:

Переменные окружения CGI

При запуске CGI-скрипта веб-сервер устанавливает дополнительные переменные окружения:

Метод аутентифицирования, использованный для опознания пользователя. См. также REMOTE_USER и REMOTE_IDENT.

Длина данных запроса в байтах, переданных CGI-скрипту через стандартный ввод.

MIME-тип данных запроса.

Корневой каталог дерева документов веб-сервера (определяется директивой DocumentRoot).

Используемая версия CGI.

Список MIME-типов данных, которые клиент может принять.

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

URL документа, в котором находилась ссылка, вызвавшая настоящий запрос.

Броузер клиента.

PATH_INFO, преобразованное в полный путь в файловой системе сервера (PATH_INFO, добавленное к DOCUMENT_ROOT).

Данные запроса, переданные в составе URL вслед за вопросительным знаком — см. выше «Структура URL и кодирование данных запроса».

IP-адрес клиента.

Метод запроса (GET, POST, HEAD и т.д.).

Номер порта сервера.

Тип и номер версии ПО веб-сервера.

Переменная Значение
AUTH_TYPE
CONTENT_LENGTH
CONTENT_TYPE
DOCUMENT_ROOT
GATEWAY_INTERFACE
HTTP_ACCEPT
HTTP_FROM
HTTP_REFERER
HTTP_USER_AGENT
PATH_INFO PATH_INFO (если есть) — см. выше «Структура URL и кодирование данных запроса»
PATH_TRANSLATED
QUERY_STRING
REMOTE_ADDR
REMOTE_HOST Имя DNS клиента.
REMOTE_USER Аутентифицированное имя пользователя.
REQUEST_METHOD
SCRIPT_NAME Виртуальный путь (например, /cgi-bin/program.pl) к исполняемому CGI-скрипту.
SERVER_NAME DNS-имя сервера или, при невозможности определить имя, его IP-адрес.
SERVER_PORT
SERVER_PROTOCOL Имя и версия протокола, через который был сделан запрос (например, HTTP/1.1).
SERVER_SOFTWARE

С Apache поставляется стандартный тестовый скрипт test-cgi, выводящий занчения переменных окружения CGI.

Cookies и другие методы сохранения состояния

Основной проблемой при написании интерактивных CGI-скриптов, т.е. скриптов, чьи последовательные вызовы одним пользователем логически связаны друг с другом, является проблема сохранения состояния. Дело в том, что в протокол HTTP рассматривает все поступающие на сервер запросы как независимые друг от друга. Соответственно, после обработки каждого вновь поступившего запроса CGI-скрипт полностью завершает свою работу, а для обработки следующего запроса, неважно относится ли он к тому же логическому сеансу работы пользователя или нет, скрипт начинает свою работу с нуля без всякой информации о предыстории.

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

Существует несколько методов сохранения состояния:

  1. cookies — сохранение на компьютере клиента,
  2. скрытые поля — сохранение внутри формы, посылаемой клиенту,
  3. сохранение в файле какого-либо формата на сервере,
  4. сохранение в параллельно работающей базе данных.

Два последних метода реализуют сохранение состояния на стороне сервера.

В качестве параллельно работающей базы данных может выступать любая из имеющихся СУБД, для обращения к которой язык программирования скрипта имеет интерфейс (в Перле есть библиотеки, обеспечивающие взаимодействие со всеми распространенными СУБД).

Также существует решение в виде демона, который запускается параллельно с http-сервером, и сохраняет требуемую информацию в своей оперативной памяти в виде переменная=значение. Для записи или извлечения данных скрипт соединяется с демоном по заранее оговоренному порту TCP или UDP, идентифицирует себя и использует набор простых команд типа «save name=value» и «extract name» (возвращается value).

Интересно, что несмотря на сложность реализации, такое решение (или использование СУБД с возможностью доступа по сети) позволяет разделять данные между скриптами работающими на различных серверах (если реализуется какая-то сложная распределенная интерактивная веб-система), при этом не вовлекается сохранение данных на стороне пользователя.

Основным недостатком сохранения данных в файле, кроме использования дискового пространства и накладных расходов на файловые операции, является операция записи на диск как таковая. Запись на диск может быть источником серьезных проблем в плане безопасности, так как работа CGI-скрипта фактически управляется воздействием внешних пользователей, которые могут иметь враждебные намерения. Путем посылки каких-либо специальных данных неаккуратно написанному скрипту можно вызвать серьезный сбой в работе сервера. Если же скрипт имеет право записи на диск, то последствия могут быть гораздо серьезнее, поэтому обычно CGI-скрипты, как и сам веб-сервер, работают с минимальными привилегиями от имени пользователя nobody без права записи на диск.

Сохранение состояния на стороне пользователя

Сохранение данных состояния на стороне пользователя (cookies и, технически, скрытые поля) существенный недостаток: пользователь имеет полный доступ к сохраняемым данным и может их несанкционированно изменить (например, прочитать правильный ответ теста или изменить идентификатор пользователя). Достоинством является простая реализация.

Cookies

Cookies — это данные вида имя=значение, которые, будучи получены от сервера, сохраняются броузером на диске пользователя для их возврата серверу при последующих запросах к этому или другому URL. Поскольку данные сохраняются на диске, они могут быть использованы после перезапуска броузера.

Сервер передает cookie через специальное поле заголовка HTTP-ответа «Set-Cookie». Броузер возвращает cookie также через специальное поле в загловке HTTP-запроса — «Cookie». На стороне сервера cookie формируется, как правило, скриптом, который просто выводит в STDOUT соответствующий заголовок. Передача данных, полученных через cookie, от броузера в скрипт производится сервером через установку переменной окружения HTTP_COOKIE, которая доступна внутри скрипта и содержит пары имя=значение, которые броузер передал внутри поля «Cookie» в заголовке своего запроса.

Формат поля Set-Cookie (HTTP-ответ)

Все элементы, кроме имя=значение и Version, не являются обязательными. В заголовке одного ответа сервера может содержаться несколько полей Set-Cookie.

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

Max-Age=секунды устанавливает срок годности данных (в секундах с момента получения cookie); по умолчанию — до окончания работы данного проуесса броузера.

Comment=текстовый_комментарий комментарий сервера по поводу предназначения cookie; предполагается, что пользователь может отказаться работать с этим cookie, если комментарий ему не понравится.

Domain=домен_сервера домен, для которого действительно данное cookie (броузер должен возвращать cookie при обращении ко всем серверам данного домена, с учетом параметра Path [см. ниже]); домен должен начинаться с точки; данный сервер должен находиться в этом домене. Если параметр Domain не указан — возвращать cookie только данному серверу.

Path=URI_или_часть_URI путь от корня дерева документов сервера (URI); броузер должен возвращать cookie при обращении к данному URI и ко всем URI, начинающимся с данного; по умолчанию — URI, при запросе которого было сгенерировано cookie, минус имя файла.

Пример: при обращении на «http://s.vvsu.ru/a/b/c» сервер выдал ответ с установленным полем в заголовке: Это значит, что cookie должно возвращаться броузером при обращении на все URL вида «http://s.vvsu.ru/a/b/какое-то_имя_файла«.
Если же SetCookie в ответе сервера выглядит вот так: то броузер должен присоединять это cookie ко всем запросам URL вида: «http://имя_без_точки.vvsu.ru/a/b/некий_путь_или_никакого«.

Secure если это параметр присутствует, то броузер должен возвращать cookie серверу только через защищенный канал связи; стандарт не специфицирует конкретный механизм защиты данных при передаче, но предполагается, что это SSL.

Формат поля Cookie (HTTP-запрос)

Параметры Path и Domain включаются только если они были установлены в заголовке Set-Cookie. Если несколько cookie удовлетворяют параметру Path, то они указываются в одном заголовке Cookie друг за другом (через точку с запятой) в следующем порядке: первыми передаются cookie с более длинным параметром Path. Порядок следования при равенстве параметров Path не определяется.

Скрытое поле создается внутри формы с помощью тега

Когда броузер получает документ с этой формой, содержимое полей типа «h >Недостатком этого метода (кроме указанной выше возможности доступа и изменения данных) является то, что данные сохраняются только во время одного сеанса работы броузера. Если броузер будет перезапущен, все данные будут утеряны и процесс взаимодействия со скриптом начнется с нуля.

Server Side Includes

SSI представляет собой механизм разбора HTML-документов на стороне сервера с целью обнаружения в документе и выполнения директив, добавляющих в документ дополнительную информацию.

Все директивы вставляются внутрь тэгов HTML-комментариев, что позволяет клиенту, в случае, если сервер не поддерживает SSI, игнорировать эти директивы. Директивы имеют следующий формат:

Ниже следует список основных директив SSI и их параметров.


echo Подставляет в документ значение указанной в качестве параметра переменной окружения (см. также список CGI-переменных) или специальной переменной SSI (см. ниже):

include Вставляет в документ текст другого файла. Параметры: file — указывает путь к вставляемому файлу относительно расположения данного документа; virtual — указывает виртуальный путь (как он указывался бы в URL) к вставляемому файлу. Эта директива очень удобна для создания стандартных шапок и подвалов веб-страниц.

fsize Вставляет размер указанного в параметре файла (путь к файлу виртуальный):

flastmod Вставляет в документ дату и время последней модификации указанного в параметре файла (путь к файлу виртуальный): Формат вывода даты и времени может быть специфицирован параметром timefmt директивы config.

exec Выполняет внешнюю программу, указанную параметром, и вставляет вывод этой программы в документ. Параметры: cmd — выполняемая программа является неким обычным приложением; cgi — выполняемая программа является CGI-скриптом В первом примере используется подстановка значений переменных окружения (см. CGI-переменные).

config Модифицирует различные аспекты работы SSI. Параметры:

  • errmsg — сообщение об ошибке, выдаваемое при невозможности выполнить директиву:
  • sizefmt — устанавливает формат вывода размера файла (подставляемого директивой fsize; значения: bytes — выводит в байтах; abbrev — округляет до целого числа килобайт.
  • timefmt — устанавливает формат вывода даты и времени, подробнее см. здесь.

Специальные переменные SSI

Ниже приведены переменные SSI, которые можно использовать в директиве echo в дополнение к переменным CGI.

DOCUMENT_NAME Имя данного документа. Например:

DOCUMENT_URL Виртуальный путь к данному документу. Например:

QUERY_STRING_UNESCAPED Декодированные данные из QUERY_STRING (см «Структура URL и кодирование данных запроса»), при этом все метасимволы шелла экранированы обратным слэшем (\).

DATE_LOCAL Текущие дата и время по местному времени. Например:

DATE_GMT Текущие дата и время по Гринвичу.

LAST_MODIFIED
Дата и время последней модификации данного документа. Например:

Задание

Написать CGI-скрипт для игры в виселицу (угадывание слова по буквам).

Сервер загадывает слово из словаря и показывает его пользователю в замаскированном виде (буквы заменены звездочками). Пользователь имеет некоторое число попыток; во время каждой попытки он может угадать одну букву. Если пользователь правильно угадывает букву или называет букву, которую он уже использовал, попытка не засчитывается. Иначе число попыток уменьшается на единицу.

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

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

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

Слова выбираются случайным образом из заданного текстового файла.

Соотношение числа попыток и длины слова разумно определяется программистом. Например, число попыток есть заданная функция от длины слова; число попыток жестко привязано к каждому слову в словаре; длина слов в словаре и число попыток являются константами; при определении числа попыток используется заявленный пользователем уровень сложности.

При первом обращении к скрипту выдается заставка и регистрационная форма вида:

При написании скрипта следует непрерывно помнить следующее основное правило CGI-программиста:

С каждым новым HTTP-запросом скрипт начинает свою работу с нуля. В данном случае: в игру может играть несколько пользователей одновременно; каждый из них последовательно формирует несколько HTTP-запросов; но для обработки каждого очередного запроса, поступившего на сервер, неважно к какому этапу игры или пользователю он относится, связан ли он с предыдущими или другими поступившими одновременно запросами, скрипт запускается с нуля и не имеет никаких знаний о своих предыдущих запусках и о состоянии игорного процесса.

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

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

Если такую информацию получить не удается, считается, что это первое обращение пользователя и ему предлагается регистрационная форма.

О методах сохранения состояния в CGI-программировании см. соответствующий раздел выше.

В результате анализа информации о состоянии игры и содержимого заполненной пользователем формы (если таковое имеется в поступившем запросе) программа разветвляется для формирования одного из следующих ответов (HTML-текстов):

  • регистрационная форма,
  • форма попытки,
  • сообщение об окончании игры.

После выдачи сформированного HTML-текста и сохранения (каким-либо способом) нового состояния, программа прекращает свою работу.

Скрипт имеет методику для подсчета очков, заработанных в игре, (алгоритм подсчета — на усмотрение программиста) и ведет таблицу чемпионов (формируется скриптом по нажатию специальной кнопки, которая демонстрируется в регистрационной форме).

Также для каждого пользователя ведется таблица его результатов; слова, уже предлагавшиеся пользователю, независимо от того, угадал он их или нет, исключаются из списка предложений.

Запуск интерпретатора и режим отладки

При запуске интерпретатора peri из командной строки можно задать разнообразные режимы его работы. Это достигается передачей ему специальных опций, называемых еще переключателями или просто ключами, включающих или выключающих разные режимы работы интерпретатора. Знание всех возможностей, предоставляемых опциями, позволяет более эффективно использовать интерпретатор для решения возникающих задач. Например, опция -е позволяет задать строку кода Perl непосредственно в командной строке. Эта возможность удобна для быстрого выполнения небольшой задачи, не прибегая к созданию файла с исходным текстом программы. Другие опции могут сэкономить время системного администратора, позволив решить некоторые задачи непосредственным вызовом peri из командной строки без написания кода достаточно большого объема.

Внутренний отладчик, которым снабжен интерпретатор peri, неоценим при отладке сложных сценариев Perl, особенно при разработке собственных модулей. Конечно, по общему признанию апологетов Perl, возможности его отладчика не так изощренны, как в С, C++ или Visual Basic, однако они могут оказаться мощным средством выявления ошибок, не обнаруживаемых самим компилятором даже в режиме отображения предупреждений.

В этой главе мы познакомимся с некоторыми опциями командной строки интерпретатора и их использованием для решения повседневных задач системного администрирования. Узнаем, как можно воспользоваться встроенным отладчиком в системе UNIX, а также изучим необходимый набор команд отладчика для выполнения основных действий в процессе обнаружения ошибок программ Perl.

14.1. Опции командной строки

Наиболее общая форма синтаксиса строки запуска интерпретатора peri имеет следующий вид:

peri [опции] [—] [файл_программы] [параметры_программы]

Опции peri задаются сразу же после имени интерпретатора и представляют собой двухсимвольные последовательности, начинающиеся с дефиса «-«:

peri -а -р prog.pl filel file2

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

peri -w -I/usr/include -0055 prog.pl filel file2

Опции без параметров можно группировать, задавая целую группу с одним дефисом. Следующие вызовы peri эквивалентны:

peri -wd prog.pl filel file2 peri -w -d prog.pl filel file2

Опции с параметрами таким способом задавать нельзя. Можно, однако, одну опцию с параметром добавить в конец группы опций без параметров:

peri -wdl/usr/include -0055 prog.pl filel file2

Передать опции для установки соответствующего режима работы интерпретатора можно непосредственно и из самой программы Perl. Первая строка сценария со специальным комментарием #! предназначена именно для этой цели:

#!/usr/bin/perl -w -d -I/usr/include

Теперь настало время узнать, какие опции существуют и как они влияют на режим работы интерпретатора. Мы решили сначала перечислить все возможные опции peri, а потом объяснить использование некоторых из них для выполнения задач системного администрирования UNIX. В табл. 14.1 представлены все опции с их кратким описанием. Советуем читателю внимательно ознакомиться с содержанием этой таблицы, так как для некоторых опций приведенное краткое описание в то же время является и исчерпывающим для понимания существа данной опции.

Таблица 14.1. Опции командной строки

Задает разделитель записей файла ввода, устанавливая значение специальной переменной $/. Необязательный параметр nnn — восьмеричный код символа; если отсутствует, принимается равным 0 (код символа \0). Эта опция удобна, если при каждом запускесценария Perl в него необходимо передавать файлы с разными символами завершения записи

Включает режим авторазбиения строки ввода при совместном использовании с опцией -п или -р (строка передается функции split ( > , а результат ее выполнения помещается в специальный массив @г). Умалчиваемый разделитель — пробел; опция -F позволяет задать регулярное выражение для иного разделителя

Проверка синтаксиса программы без ее выполнения (блоки BEGIN, END и use выполняются, так как это необходимо для процесса компиляции)

Запускает сценарий в режиме отладки под управлением модуля отладки или трассировки, установленного как

Устанавливает флаги отладки

Выполнение строки кода Perl, заданной параметром этой опции, а не файла сценария файл_программы, указанного в командной строке вызова интерпретатора. В строке кода можно задать несколько операторов, разделенных символом ‘;’. Допускается задание нескольких опций -е. (В Windows строка кода задается в двойных кавычках и для использования самих кавычек в коде Perl необходимо применять управляющую последовательность \».)

Задает регулярное выражение для разделителя при автоматической разбивке строки файла ввода в случае задания опции -а. Например, -F/-.+/ определяет в качестве разделителя одно или более двоеточий. По умолчанию используется пробел / /. Символы «/» при задании per выраж не обязательны

Задает режим редактирования по месту файла, переданного как параметр в сценарий Perl. Используется совместно с опциями -п или -р. Редактирование выполняется по следующей схеме: файл переименовывается (если задано расширение), открывается файл вывода с именем исходного файла и все операции print ( ) сценария осуществляют вьшод в этот новый файл.

Параметр расширение используется для задания имени копии файла по следующей схеме: если в нем нет символов «*», то оно добавляется в конец имени исходного файла; каждый символ «*» этого параметра заменяется именем исходного файла

Задает каталог поиска сценариев Perl, выполняемых операциями do, require и use (сохраняется как элемент специального массива @INC). Также задает каталоги размещения файлов, включаемых в сценарий Perl директивой finclude препроцессора С. Можно использовать несколько опций для задания необходимого количества каталогов поиска

Включает автоматическую обработку концов строк ввода. Работа в этом режиме преследует две цели:

1. Автоматическое удаление завершающего символа записи, хранящегося в специальной переменной $/, при включенном режиме -п или -р;

2. Присваивание специальной переменной $\, в которой хранится символ завершения записи при выводе операторами print, восьмеричного значения nnn, представляющего код символа завершения; если этот параметр не задан, то переменной $\ присваивается текущее значение $ /

-m[-] мо дуль -М [ — ] модуль

-[гаМ][-] модуль= пар! [ , пар2 ] . .

Выполняет оператор use module О (опция -т) или use module (опция -м) перед выполнением сценария Perl. Если параметр модуль задан с дефисом, то use заменяется на по. Третья форма этих опций позволяет передать параметры в модуль при его загрузке

Заданный сценарий Perl выполняется в цикле

Это позволяет обработать программой Perl в цикле каждую строку всех файлов, имена которых переданы в качестве параметров сценария Perl. Эта опция эмулирует функциональность sed с ключом -п и awk

Аналогичен опции -п, но добавляется печать каждой обрабатываемой строки, как в редакторе sed:

Перед компиляцией сценарий Perl обрабатывается препроцессором С, что позволяет использовать в нем команды препроцессора #define, # include и все команды условной компиляции С (#if, felse и т. д.). В опции -I можно задать каталоги расположения файлов, включаемых командой t include

Включает режим синтаксического анализа строки вызова сценария Perl на наличие после имени файла сценария, но до параметров имен файлов «пользовательских опций» (параметров, начинающихся с дефиса). Такие параметры извлекаются из массива @ARGV и в программе объявляются и определяются переменные с именами введенных опций. Следующий сценарий напечатает «Задана опция optl» тогда и только тогда, когда он будет вызван с опцией -optl:

Поиск файла программы Perl файл программы осуществляется с использованием значения переменной среды PATH

Включает режим проверки на безопасность полученных извне данных в операциях с файловой системой. Полезен при реализации CGI-сценариев. Эта опция должна быть первой в списке опций интерпретатора peri, если она применяется к сценарию

Создание дампа ядра после компиляции сценария Perl. Последующее использование программы undump позволяет создать двоичный выполняемый файл сценария

Разрешает выполнение небезопасных операций. При использовании этой опции в UNIX программа Perl выполняется в незащищенном режиме и ей предоставляется полный доступ к файловой системе

Отображает номер версии, а также другую важную информацию об интерпретаторе peri

Отображает информацию конфигурации интерпретатора peri (расположение необходимых библиотек, значения переменных среды и т. д.). Если задано имя переменной среды, отображает ее установленное значение

Включает режим отображения предупреждений во время компиляции программы Perl. Рекомендуется всегда применять эту опцию

Извлекает и выполняет сценарий Perl, расположенный в текстовом файле. Эта возможность удобна, если сценарий прислан по электронной почте. Интерпретатор сканирует файл, пока не найдет строку, начинающуюся с символов «# ! » и содержащую слово «peri». После этого выполняется сценарий до лексемы END . Если задан параметр каталог, то перед выполнением сценария он становится текущим

Как видно из табл. 14.1, интерпретатор peri располагает достаточно большим набором опций, разработанных специально в помощь системному администратору UNIX. Эти опции позволяют решать задачи, даже не прибегая к созданию текстового файла сценария Perl.

Одной из наиболее часто встречающихся задач системного администрирования является задача обработки содержимого большого числа файлов и данных (например, изменение значений некоторых переменных среды в конфигурационных файлах). Можно написать сценарий Perl, в цикле обрабатывающий строки переданных ему файлов, а можно воспользоваться опциями -п или -р, которые организуют цикл по файлам, и задать необходимые действия для каждой строки файла в опции -е. Таким образом, быстрота решения задачи гарантирована!

Итак, мы хотим в конфигурационных файлах configl, config2 и configS, содержащих строки вида ключ = ЗНАЧЕНИЕ, изменить значение ключа «кеу!» на величину 5. Эта задача решается следующим вызовом peri из командной строки:

if($l eq V’KeylV)<$_ = \"$1 = 5\n\";>;» configl config2 configS

Несколько комментариев к строке вызова интерпретатора peri. В ней использованы опции -р и -i для обработки содержимого конфигурационных файлов по месту (опция -i, причем задано расширение .bak для копий исходных файлов) в неявном цикле с печатью] (опция -р). Код модификации содержимого файлов задается с помощью о/щии -е. Он достаточно прост. Строка файла, прочитанная в специальнуюЛтеременную Perl $_, проверяется на содержание подстроки вида ключ = ЗНАЧЕНИЕ. В регулярном выражении определены две группы: первая соответствует ключу, а вторая — его значению. Таким способом мы сохраняем имя ключа и его значение в специальных переменных $1 и $2, соответственно. Второй оператор кода, в случае совпадения имени ключа с заданным, заносит в переменную $_ строку с новым значением ключа (кеу! = 5).

Как выполняется этот сценарий? Создается копия исходного конфигурационного файла configl (файл configl.bak) и новый пустой файл с именем configl. Последовательно в переменную $_ читаются строки из файла-копии, а в переменную $1 заносится имя ключа, если таковой обнаружен оператором т/. /. Если имя ключа равно «Keyi», то в переменной $_ формируется строка задания нового значения ключа. Перед чтением следующей строки файла configl.bak в файл configl записывается содержимое переменной $_. Эта процедура выполняется со всеми заданными конфигурационными файлами. В результате выполнения этой программы формируются конфигурационные файлы, в которых значение ключа Keyi изменено на 5.

Опция -р достаточна полезна для анализа содержимого файлов. Например, следующая команда отобразит на экране содержимое файла prog.pl:

peri -p -е»1″ prog.pl

Замечание Задание кода программы Perl при работе с интерпретатором peri является необходимым действием. Его можно задать, указав имя файла программы после всех опций, либо непосредственно в командной строке в опции -е. При печати содержимого файла мы задали в командной строке программу из одного оператора, который, по существу, ничего не делает.

При работе с интерпретатором из командной строки очень часто используются регулярные выражения для отображения какой-либо части содержимого файла. Следующий вызов peri отображает на экране монитора последний столбец данных из файла test.dat (элементы столбцов в строке файла разделены пробелами):

Замечание При использовании опции -р следует помнить, что она печатает содержимое специальной переменной $_. Поэтому информацию, подлежащую отображению, следует помещать именно в эту переменную, как в последнем примере.

Можно было бы привести еще массу полезных примеров вызова интерпретатора peri с различными опциями для решения разнообразных задач, но мы ограничимся приведенными примерами. При написании этой главы мы ставили целью всего лишь показать, на что способен интерпретатор peri. Думайте, размышляйте, и вы сможете решать многие задачи, не прибегая к написанию больших файлов с кодом Perl.

14.2. Отладчик Perl

Написав программу и устранив ошибки компиляции, любой программист втайне надеется, что она будет работать именно так, как он и задумывал. Практика, однако, в большинстве случаев совершенно иная: при первом запуске программа работает, но выполняет не совсем, а иногда и совсем не то, что надо; при одних исходных данных она работает идеально, а при других «зависает». И это случается не только с начинающим, но и с опытным программистом. В таких случаях на помощь приходит отладчик — специальная программа, которая позволяет программисту, обычно в интерактивном режиме, предпринять определенные действия в случае возникновения необычного поведения программы.

Для вызова встроенного отладчика интерпретатора peri его необходимо запустить с опцией -d (задав ее либо в командной строке, либо в строке специального комментария I! самой программы). Отладчик инициируется, когда начинает выполняться сценарий Perl. При этом отображается версия отладчика, первая выполняемая строка кода программы и его приглашение DB на ввод команд пользователя:

Loading DB routines from perl5db.pl version 1.0402 Emacs support available.


Enter h or *h h’ for help.

main::(examplel.pl:3): print «\000\001\002\003\004\005\006\007\n»; DB

После чего можно вводить команды отладчика для выполнения определенных действий: установить точки останова, определить действия при выполнении определенной строки кода Программы, посмотреть значения переменных, выполнить часть кода сценария и т. д. Эта глава и посвящена краткому описанию команд, задающих необходимые действия при отладке разработанного сценария Perl. Мы здесь не учим стратегии поиска ошибок, а только лишь показываем возможности отладчика при ее реализации.

Замечание Все, что здесь говорится о встроенном отладчике, относится к пользователям системы UNIX. Тот, кто работает в системах семейства Windows и пользуется интерпретатором peri фирмы ActiveState, может совсем не читать этот раздел, так как интерпретатор этой фирмы снабжен отладчиком, работа с которым осуществляется через графический интерфейс пользователя, а не с помощью командной строки. Хоти ничто не мешает таким пользователям воспользоваться встроенным отладчиком, аналогичным отладчику интерпретатора peri для UNIX, и работать с ним из командной строки. Для этого следует воспользоваться командным файлом cmddb.bat, расположенным в каталоге \perl520\debugger.

14.2.1. Просмотр текста программы

При загрузке отладчика отображается первая строка кода программы Perl. Но для выполнения определенных действий (установки точки останова, задания определенных действий при выполнении конкретного оператора Perl и т. д.) нам необходимо видеть текст программы. Как это осуществить? В отладчике для подобных действий предусмотрен ряд команд.

Команда i отображает на экране монитора 10 строк текста программы, расположенных непосредственно за последней отображенной строкой. Последовательное выполнение этой команды позволяет быстро пролистать текст программы. Вызов команды i с указанием номера строки отобразит ее содержимое. Несколько последовательных строк программы можно увидеть, задав в команде i через дефис номер начальной и конечной строки. Например, команда 1 1-5 отобразит пять строк программы:

DB 1 1-5 1 #! peri -w

2==> open FILE, «books» or die $!; 3: open REPORT, «>report»; 4 5: select REPORT;

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

Команда w отобразит блок, или окно строк — три строки до текущей, текущая строка и шесть после текущей. Текущей в отладчике считается строка программы после последней отображенной. Если команде w передать номер строки, то отобразится окно строк относительно заданной строки текста — три строки до заданной, сама заданная строка и шесть после нее.

Последняя команда отображения текста программы — команда — (дефис), которая отображает 10 строк текста, предшествующих текущей строке.

14.2.2. Выполнение кода

Команда s предназначена для последовательного пошагового выполнения программы: каждый ее вызов выполняет следующую строку кода. Эта строка должна выполняться в программе без изменения потока выполнения операторов. После выполнения очередной строки кода отображается строка, которая должна быть выполнена следующей:

DB s main: : (exaitple2.pl:3) : @s = split;

При следующем выполнении команды s будет выполнена отображенная строка программы: @s = split;.

Если следующая выполняемая строка кода расположена в модуле, код которого доступен (например, вызов подпрограммы), то осуществляется переход в него, соответствующая строка кода выполняется и отладчик приостанавливает выполнение программы до ввода следующей программы. Последующие команды s будут построчно выполнять код подпрограммы, пока не выполнится последняя строка ее кода. Таким образом, команда s позволяет выполнять подпрограмму с заходом в нее.

Команда п работает аналогично команде s, последовательно выполняя строки кода программы, за одним исключением — она выполняет код подпрограммы без захода в него, т. е. код подпрограммы выполняется полностью, и при следующем вызове команды п выполняется оператор строки кода, непосредственно следующей за строкой с вызовом подпрограммы. Таким образом, команда п позволяет «обойти» пошаговое выполнение операторов подпрограммы.

Если мы осуществляем пошаговое выполнение программы (командами s или п), то нажатие клавиши эквивалентно вызову последней команды s или п.

Если мы в процессе отладки попали в тело подпрограммы (после, например, выполнения очередной команды s), то командой г можно немедленно завершить ее выполнение. Выполнение программы приостанавливается на первом после вызова подпрограммы операторе в ожидании очередной команды пользователя. \

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

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

14.2.3. Просмотр значений переменных

В процессе отладки можно посмотреть значение любой переменной программы в любой момент времени. Команда

V [пакет [переменная]]

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

При работе с этой командой следует иметь в виду, что при задании переменной, значение которой необходимо посмотреть, не надо задавать никакого префикса, а только идентификатор переменной. Отладчик отобразит значения всех переменных указанного пакета с заданным идентификатором. Например, если в программе определена скалярная переменная $ref, маесив скаляров @ref и хеш-массив %ref, то выполнение команды v main ref приведет к следующему результату:

DB V main ref $ref = 24 @ref = ( 1

Команда х аналогична команде v, но она отображает значения переменных текущего пакета. Ее параметром является идентификатор переменной, имя пакета указывать не надо. Вызванная без параметров, она отображает значения всех переменных текущего пакета. Например, команда х ref отобразит значения переменной $ref, массива @ref и хеш-массива %ref текущего пакета, внутри которого приостановлено выполнение программы. По умолчанию программа выполняется в пакете main.

Команда t работает как переключатель, включая режим отображения строк выполняемого кода (режим трассировки) или выключая его:

main::(example2.pl:3): @ref = (1,2,3,4); main::(example2.pl:4): %ref = («One»,l, «Two»,2); main::(example2.pl:5): $_ = » qwerty \t\tqwerty»;

DB t Trace = off

DB с 7 main::(example2.pi:7): mySub();

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

14.2.4. Точки останова и действия

В процессе отладки программы возникает необходимость приостановить ее выполнение в определенных подозрительных иестах, посмотреть значения

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

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

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

I устанавливает точку останова в первой строке кода подпрограммы mySub.

Иногда необходимо, чтобы выполнение программы приостанавливалось в некоторой точке программы только при выполнении каких-либо условий (например, равенства заданному числу значения какой-нибудь переменной, или совпадения значений двух других переменных и т. п.). Команда ь позволяет задавать подобные условные точки останова. Для этого ей можно передать в качестве второго параметра условие, при истинности которого точка останова будет восприниматься отладчиком как действительная точка останова. Если условие перед выполнением строки кода не будет истинно, то останова программы в этой точке не произойдет. Например, следующая команда

определяет условную точку останова в строке 4. Отладчик приостановит выполнение программы перед этой строкой по команде с только, если значение переменной $г будет равно 1.

Команда L отображает список всех установленных точек останова, как безусловных, так и условных:

DB b 4 $г==1 DB b 6 DB L

Iexample2.pl: . •. -. , 4: %ref = («One». «Two»,2);

break if ($r==l) 6: @s = split;

Отображаемая информация о точке останова представляет номер строки и код Perl, а также условие, при котором действует точка останова (break

if (УСЛОВИЕ)). Для безусловной точки останова условие всегда истинно и равно 1.

Для удаления точки останова достаточно выполнить команду d с параметром, равным номеру строки, в которой определена точка останова. Команда о удаляет все точки останова, определенные в сеансе работы с отладчиком.

Полезно при отладке программы задать действия, которые будут предприняты перед выполнением операторов определенной строки. Например, напечатать значения каких-либо переменных или изменить их при выполнении некоторого цикла. Подобное поведение программы можно реализовать, задав действия командой а. Два ее параметра определяют строку кода и сами действия (обычный оператор Perl) перед началом выполнения операторов заданной строки:

а 75 print «*** $ref\n»;

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

Любое действие можно выполнить немедленно, набрав код в строке приглашения отладчика DBO. Подобные действия не изменяют текст программы (операторы действий не записываются в ее файл), но позволяют создавать новые переменные и использовать их в вычислениях. Правда, по завершении сеанса отладки подобная информация пропадает.

Мы познакомили читателя лишь с основными командами отладчика, наиболее важными и полезными, с нашей точки зрения, для процесса поиска ошибок. Их полный набор с краткими описаниями представлен в табл. 14.2. Более подробную информацию можно всегда найти в документации, с которой распространяется Perl, или из различных ресурсов Internet.

Таблица 14.2. Основные команды отладчика

Как устранить мой Perl CGI скрипт?

У меня есть сценарий Perl, который не работает, и я не знаю, как начать сужать проблему. Что я могу сделать?

Примечание: Я добавляю вопрос, потому что я действительно хочу, чтобы добавить свой самый длинный ответ на Stackoverflow. Я держу внешне ссылки на него в других ответах и ​​заслуживает того, чтобы быть здесь. Не стесняйтесь редактировать свой ответ, если у вас есть что-то добавить.

Этот ответ предназначен в качестве общей основы для работы через проблемы с CGI скриптов Perl и первоначально появились на Perlmonks , как и устранение неисправностей Perl CGI скриптов . Это не полное руководство по каждой проблеме, вы можете столкнуться, ни учебник по ошибке деформируя. Это просто кульминация моего опыта сценариев отладки CGI десять (плюс!) Лет. Эта страница , кажется, было много разных домов, и я , кажется, забывают , что существует, поэтому я добавляю его в StackOverflow. Вы можете отправить любые комментарии или пожелания по bdfoy@cpan.org. Это также сообщество вики, но не переборщите орехи. :)

Используете ли вы в Perl встроенных функций, чтобы помочь вам найти проблемы?

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

Тем не менее, вы должны заставить себя всегда очистить сомнительный код, добавив warnings прагму ко всем файлам:

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

Возможно, вы имели выходной действительный CGI заголовок первого?

Сервер ожидает первый выход из сценария CGI , чтобы быть заголовок CGI. Как правило , это может быть так просто , как print «Content-type: text/plain\n\n»; и с CGI.pm и его производных, print header() . Некоторые сервера чувствительны к ошибкам вывода (на STDERR ) , показывающих перед стандартным выводом (на STDOUT ).

Попробуйте отправить ошибки в браузере

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

Что сказать, журнал ошибок?

Серверы держать журналы ошибок (или они должны, по крайней мере). Выход ошибки с сервера и из вашего сценария должен появиться там. Найти журнал ошибок и посмотреть , что он говорит. Существует не стандартное место для файлов журналов. Посмотрите в конфигурации сервера для их размещения, или попросите администратора сервера. Вы можете также использовать инструменты , такие как C :: Ca , чтобы сохранить ваши собственные файлы журналы.

Какие разрешения сценария?

Если вы видите ошибки , такие как «Отказано в доступе» или «метод не реализован», это , вероятно , означает , что ваш сценарий не может быть прочитан и исполняемым пользователем веб — сервера. На разновидностях Unix, изменить режим 755 рекомендуется: chmod 755 filename . Никогда не устанавливайте режим в 777!

Используете ли вы use strict ?

Помните , что Perl автоматически создает переменную при первом использовании их. Это особенность, но иногда может вызвать ошибки , если вы ошиблись при вводе имени переменной. Прагма use strict поможет вам найти те виды ошибок. Это раздражает , пока вы не привыкнете к нему, но ваше программирование значительно улучшится после того, как некоторое время , и вы будете свободны делать различные ошибки.

компилировать ли сценарий?

Вы можете проверить на наличие ошибок компиляции с помощью -c переключателя. Сконцентрируйтесь на первые ошибки сообщили. Промыть, повторите. Если вы получаете действительно странные ошибки, убедитесь , что ваш сценарий имеет правильные окончания строк. Если FTP в двоичном режиме, извлечение из CVS, или что — то другое , что не обрабатывает конец строки перевода, веб — сервер может увидеть ваш сценарий как один большой линии. Передача скриптов Perl в режиме ASCII.

Является ли сценарий жалуясь небезопасными зависимостями?

Если ваш скрипт жалуется на ненадежных зависимости, вы, вероятно , с помощью -T переключателя , чтобы включить режим меченого, который является хорошей вещью , так как он держит вас передавая непроверенные данные в оболочку. Если жалуясь он делает свою работу , чтобы помочь нам написать более безопасные сценарии. Любые данные , исходящие из внешней программы (т.е. среды) считаются испорченными. Переменные окружения , такие как PATH и LD_LIBRARY_PATH особенно нежелательны. Вы должны установить их в безопасное значение или убрать их полностью, как я рекомендую. Вы должны использовать абсолютные пути в любом случае. Если проверка порчи жалуется на что — то другое, убедитесь , что у вас есть незапятнанные данные. См perlsec для уточнения деталей.

Что происходит, когда вы запустите его из командной строки?

Вывод сценария , что вы ожидаете ли при запуске из командной строки? Является ли выход заголовка первого, а затем пустая строка? Помните , что STDERR могут быть объединены с , STDOUT если вы находитесь на терминале (например , интерактивная сессия), и из — за буферизации может отображаться в случайном порядке. Включите функцию AutoFlush Perl, установив $| к истинному значению. Как правило , вы можете увидеть $|++; в программах CGI. После установки, каждая печать и запись будет сразу перейти к выходу , а не буфер. Вы должны установить это для каждого дескриптора. Используйте , select чтобы изменить дескриптор файла по умолчанию, например , так:

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

Что происходит, когда вы запустите его из командной строки с CGI-средой?

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

Отозвать или удалить эти переменные

  • PATH
  • LD_LIBRARY_PATH
  • все ORACLE_* переменные

Установите эти переменные

  • REQUEST_METHOD (установлен GET , HEAD или POST в зависимости от обстоятельств)
  • SERVER_PORT (Устанавливается равным 80, как правило)
  • REMOTE_USER (Если вы делаете защищенный материал доступа)

Последние версии CGI.pm (> 2,75) требуют -debug флаг , чтобы получить старый (полезный) поведение, так что вы , возможно , придется добавить их к CGI.pm импорту.

Используете ли вы die() или warn ?

Эти функции печати , STDERR если вы не пересмотрели их. Они не выводит заголовок CGI, либо. Вы можете получить ту же функциональность с пакетами , такими как CGI :: Carp

Что происходит после того, как вы очистить кэш браузера?

Если вы думаете, что ваш скрипт делает правильно, и при выполнении запроса вручную, вы получите правильный выход, браузер может быть виновником. Очистить кэш и установить размер кэша до нуля во время тестирования. Помните, что некоторые браузеры действительно глупы и не будет на самом деле перезагрузить новое содержание, даже если вы скажете ей сделать это. Это особенно распространено в тех случаях, когда URL путь тот же, но изменения содержания (например, динамические изображения).

Есть сценарий, где вы думаете, что это?

Путь файловой системы к сценарию не обязательно напрямую связана с URL-путь к сценарию. Убедитесь, что у вас есть правильный каталог, даже если у вас есть, чтобы написать короткий тестовый скрипт, чтобы проверить это. Кроме того, вы уверены, что вы изменяете нужный файл? Если вы не видите никакого эффекта с вашими изменениями, вы можете быть изменения в другой файл, или загрузить файл в неправильном месте. (Это, кстати, моя самая частая причина таких неприятностей;)

Используете ли Вы CGI.pm , или производные от него?

Если ваша проблема связана с разбором ввода CGI , и вы не используете широко испытанный модуль , как CGI.pm , CGI::Request , CGI::Simple или CGI::Lite , использовать модуль и получить от жизни. CGI.pm имеет cgi-lib.pl режим совместимости , который может помочь вам решить входные проблемы из — за старые реализации парсера CGI.

Использовали ли вы абсолютные пути?


Если вы работаете с внешними командами system , обратно клещами или другими IPC средства, вы должны использовать абсолютный путь к внешней программе. Мало того, что вы точно знаете , что вы работаете, но вам избежать некоторых проблем безопасности , а также. Если вы открываете файлы для любого чтения или записи, использовать абсолютный путь. Сценарий CGI может иметь различное представление о текущем каталоге , чем вы. Кроме того , вы можете сделать явное , chdir() чтобы поставить вас в нужном месте.

Вы проверить возвращаемые значения?

Большинство функций Perl сообщит вам , если они работали или нет , и будет установлен $! на провал. Проверили ли вы возвращаемое значение и проверьте $! наличие сообщений об ошибках? Проверили ли вы , $@ если вы используете eval ?

Какую версию Perl вы используете?

Последняя стабильная версия Perl является 5.16.2. Вы используете старую версию? Различные версии Perl могут иметь разные представления предупреждений.

Какой сервер веб вы используете?

Различные серверы могут действовать по-разному в одной и той же ситуации. Тот же самый продукт сервер может действовать по-разному с разными конфигурациями. Включите как можно больше этой информации, как вы можете в любой просьбе о помощи.

Вы проверили документацию сервера?

Серьезные CGI программисты должны знать, как много о сервере, как это возможно — в том числе не только серверных функций и поведения, но также и в локальной конфигурации. Документация для сервера не может быть доступна для вас, если вы используете коммерческий продукт. В противном случае, документация должна быть на вашем сервере. Если это не так, искать его в Интернете.

Вы поиск в архиве comp.infosystems.www.authoring.cgi ?

Вполне вероятно, что кто-то имел проблему раньше, и что кто-то (возможно, мне) ответил на это в этой группе новостей. Хотя эта группа новости прошла свой апогей, собранная мудрость из прошлого иногда может быть полезно.

Вы можете воспроизвести проблему с коротким тестовым скриптом?

В крупных системах может быть трудно отследить ошибку, так как очень много вещей, которые происходят. Попробуйте воспроизвести проблемное поведение с кратчайшим сценарием. Зная проблемы является большой частью исправить. Это может быть, конечно, отнимает много времени, но вы не нашли проблему еще и вы бежите из вариантов. :)

Вы решили пойти в кино?

Шутки в сторону. Иногда мы можем получить так завернутый в проблему, что мы развиваем «воспринимаемое сужению» (туннельное зрение). Сделав паузу, получить чашку кофе, или взрывных некоторых плохих парней в [Duke Nukem, Quake, Doom, Halo, COD] может дать вам свежий взгляд, что вам нужно заново подойти к решению проблемы.

Вы вокализация проблемы?

Серьезно снова. Иногда объясняя проблему вслух приводит нас к нашим собственным ответам. Поговорите с пингвина (плюшевая игрушка) , потому что ваши сотрудники не слушают. Если вы заинтересованы в этом , как серьезный инструмент отладки (и я рекомендую, если вы не нашли проблему, сейчас), вы могли бы также прочитать Психология компьютерного программирования .

Я думаю , CGI :: Debug стоит упомянуть также.

Интересно , как же никто не упомянул PERLDB_OPTS вариант называется RemotePort ; хотя по общему признанию, здесь не так много рабочих примеров в Интернете ( RemotePort даже не упоминается в perldebug ) — и это было своего рода проблематично для меня , чтобы придумать с этим, но здесь идет (это являющийся примером Linux).

Для того, чтобы сделать правильный пример, первый мне нужно было что — то , что может сделать очень простую имитацию CGI веб — сервера, предпочтительно через одну командную строку. После нахождения простого веб — сервера из командной строки для запуска CGI скрипты. (perlmonks.org) , я нашел IO :: All — крохотный веб — сервер , чтобы быть применимо для этого теста.

Здесь, я буду работать в /tmp директории; скрипт CGI будет /tmp/test.pl (приведен ниже). Обратите внимание , что IO::All сервер будет обслуживать только исполняемые файлы в том же каталоге, что и CGI, поэтому chmod +x test.pl здесь требуется. Таким образом, чтобы сделать обычный тест CGI бежать, изменить директорию на /tmp в терминале, и запустить веб — сервер , один-лайнер есть:

Команда веб — сервер будет блокировать в терминале, и в противном случае запустить веб — сервер локально (на 127.0.0.1 или localhost ) — после этого, я могу пойти в веб — браузере, и запросить этот адрес:

. и я должен соблюдать print S , сделанные test.pl загружаемой — и показал — в веб — браузере.

Теперь, чтобы отладить этот скрипт с RemotePort , сначала нужен слушатель в сети, через которую мы будем взаимодействовать с отладчиком Perl; мы можем использовать инструмент командной строки netcat ( nc увидел , что здесь: Perl如何удаленной отладки? ). Таким образом, первым запустить netcat слушателя в одном терминале — где он будет блокировать и ждать соединения на порт 7234 (который будет нашим отладочный порт):

Затем, мы хотим , perl чтобы начать в режиме отладки с RemotePort , когда test.pl был вызван (даже в режиме CGI, через сервер). Это, в Linux, можно сделать с помощью следующего «притона обертки» сценария — который здесь также должен быть /tmp и должно быть исполняемыми:

Это своего рода сложная вещь — увидеть скрипт — Как я могу использовать переменные окружения в моем притон? — Unix и Linux Стек Обмен . Но хитрость здесь , кажется, не раскошелиться на perl интерпретатор , который обрабатывает test.pl — так , как только мы попали, мы не exec , но вместо этого мы называем perl «ясно», и в основном «источник» наш test.pl скрипт с помощью do (см Как запустить сценарий Perl из сценария Perl? ).

Теперь, когда мы имеем perldbgcall.sh в /tmp — мы можем изменить test.pl файл, так что он относится к этому исполняемому файлу на его притон линии (вместо обычного интерпретатора Perl) — здесь /tmp/test.pl измененном следующим образом:

Теперь, как test.pl и его новый обработчик притон, perldbgcall.sh , в /tmp ; и мы nc прослушиваем отладки соединений на порт 7234 — таким образом , мы можем , наконец , открыть другое окно терминала, перейдите в директорию /tmp , и запустить один-лайнер веб — сервер (который будет прослушивать веб — соединения на порт 8080) есть:

После того, как это будет сделано, мы можем перейти на наш веб — браузер, и запросить тот же адрес, http://127.0.0.1:8080/test.pl . Однако теперь , когда веб — сервер пытается выполнить сценарий, он будет делать это через perldbgcall.sh хижину — которая начнется perl в режиме удаленного отладчика. Таким образом, выполнение скрипта будет приостановлено — и поэтому веб — браузер будет блокировать, ожидая данных. Теперь мы можем перейти к netcat терминалу, и мы должны увидеть знакомый Perl отладчик текст — однако, выход через nc :

Как фрагмент кода показывает, мы теперь в основном используют nc как «терминал» — таким образом , мы можем ввести r (и Enter) для «запуска» — и сценарий будет работать до делать точки останова заявление (см также в Perl, в чем разница между $ DB :: сингл = 1 и 2? ), прежде чем снова остановить (примечание в тот момент, браузер будет по- прежнему блокировки).

Итак, теперь мы можем, скажем, шаг до конца test.pl , через nc терминал:

. однако, на данный момент, браузер блокирует и ожидает данных. Только после того, как мы выходим из отладчика с q :

. делает браузер стоп замка — и , наконец , отображает (полный) вывод test.pl :

Конечно, этот вид отладки можно сделать даже без запуска веб-сервера — однако, опрятная вещь здесь, является то, что мы не касаемся веб-сервера на всех; мы вызываем исполнение «родное» (для CGI) через веб-браузер — и только необходимые изменения в самой CGI скрипте, является изменением притона (и, конечно же, наличие сценария притона обертки, как исполняемый файл в том же каталог).

Ну, надеюсь , что это поможет кому — то — я уверен , что любил бы наткнулись на это, вместо того , чтобы писать его сам :)
Ура!

Perl и CGI программы — особенности использования

1. Использование готовых скриптов

Если у вас уже есть написанные CGI-скрипты, то прежде чем скопировать их на сервер, вы должны сделать следующие действия:

  • Убедиться, что в скриптах указан правильный путь к интерпретатору:

Perl: /usr/bin/perl
Python : /usr/local/bin/python

  • Если вашему скрипту требуется доступ к базе данных MySQL , то необходимо указать параметры доступа (см. статью Подключение к серверу MySQL)
  • В разделе Управление веб-серверомпанели управления хостингом включить модуль CGI.

Теперь вы можете скопировать свои скрипты на сервер.
Загружать файлы необходимо в каталог ваш_домен/cgi. Файлы из данного каталога будут доступны по адресу http://ваш_домен/cgi-bin/имя_файла. Для того чтобы CGI-скрипты запускались из корневого каталога сайта ваш_домен/docs, необходимо создать в нем файл .htaccess со следующим содержимым:

На скрипты необходимо установить права доступа 755 или -rwxr-xr-x.
Права доступа можно изменить с помощью файлового менеджера панели управления.

2. Написание простейшего CGI-скрипта

Рассмотрим написание простого CGI скрипта на Perl.
Если вы работаете под управлением ОС «Windows», то для работы с кодом скриптов вам необходимо использовать специализированный текстовый редактор, например, Notepad++. Стандартную для Windows программу «Блокнот» лучше не использовать. Для демонстрации работы CGI скрипта необходимо создать два файла. Первый файл представляет собой html-документ с формой ввода текста:

HTML PUBLIC «-//W3C//DTD HTML 4.0//EN»>

Пример работы с Perl

CGI-программы, использование Perl

Установка модулей Perl

Устанавливать модули Perl лучше всего используя CPAN shell. Необходимо зайти в unix shell и набрать команду:

После этого можно установить любой модуль командой

Рекомендуем при первой настройке CPAN shell выбрать один из серверов-зеркал, перечисленных в категории «Europe/Russia».

В случае необходимости вы можете отредактировать конфигурационный файл — /home/ uXXXXX/.cpan/CPAN/MyConfig.pm , где uXXXXX номер вашей виртуальной площадки.

Важно:

При первичном конфигурировании CPAN shell на вопрос: надо ответить:

Именно в этом случае все необходимые модули будут корректно устанавливаться в ваш домашний каталог.

Установка модулей Perl с помощью Makefile.PL

К сожалению, не все модули можно установить с помощью CPAN, обладая ограниченным правами пользователя площадки. В следующем примере мы рассмотрим установку модуля String::CRC32.

Сначала найдем модуль на сайте http://search.cpan.org/, введя в строку поиска название этого модуля. Далее выбираем вторую ссылку из самого первого результата поиска:

копируем url на модуль из ссылки Download;

загружаем архив на площадку:

распаковываем полученный архив:

выполняем следующие команды:

Чтобы использовать модуль, добавьте в скрипт следующую строку

Классификация ошибок

Ошибки делятся на шесть основных категорий (перечислены по степени сложности):

Ошибки формата файла

В операционных системах Unix, Windows для завершения строки используются разные символы.

Это может вызвать проблемы, если вы редактируете свою программу в операционной системе одного типа, а затем запускаете ее в другой ОС. Иными словами, если вы создаете и (или) редактируете свои программы на Windows, а ваш Internet-провайдер использует Web-сервер на базе Unix, необходимо удостовериться, что файл вашей программы сохранялся с соответствующими разделителями строк.

Один из простых способов сделать это — открыть файл на своем Web-сервере и посмотреть, есть ли в конце, каждой строки какие-нибудь странные символы.

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

Например, редактор vi их показывает, а less — нет.

Многие современные текстовые редакторы предусматривают возможность задавать тип разделителей строк, поэтому проверьте, сохраняете ли вы файл в формате, подходящем для вашего Web-сервера.

Если вы пересылаете файлы на свой Web-сервер с помощью FTP, убедитесь в том, что ваш FTP-клиент настроен на пересылку файлов в текстовом (ASCII), а не в двоичном (binary) режиме. Во многих случаях это гарантирует автоматическое преобразование разрывов строк и помогает избежать проблем.

Ошибки доступа к файлам и интерпретатору Perl

Рекомендуем выводить ошибки интерпретатора Perl при тестировании работы скрипта в окно вашего браузера. Для установки данного режима, на время отладки, необходимо вписать в начале скрипта:

Первая строка вашего скрипта должна указывать путь к интерпретатору Perl:

Убедитесь в отсутствии символа возврата каретки (код 0x0D) , в строках скрипта должен быть только символ перевода строки (код 0x0A). Права для CGI скриптов, а также для директории, содержащей скрипты, должны быть выставлены «-rwxr-xr-x», например такой командой:

Синтаксические ошибки

В Perl есть специальное средство, которое позволяет из командной строки проверять программу на наличие синтаксических ошибок, В Unix или Windows (с использованием командного процессора DOS) это делается путем ввода следующей строки на приглашение ОС:

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

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

Закончив корректировку, попробуйте запустить программу из командной строки без применения ключа -с и посмотрите, выдаст ли она правильную стандартную информацию. (Это может быть HTML-страница ошибок, если программа ожидает ввода данных через форму.)

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

Ошибки конфигурации

Программу можно настроить, используя набор переменных конфигурации, которые определяются либо в начале программы, либо в отдельном файле конфигурации. Одни из этих переменных предназначены для конфигурирования опций программы, а другие указывают на местонахождение различных вспомогательных файлов. (Такой подход облегчает настройку поведения программы без внесения изменений в код).

Если переменные, в первую очередь указывающие на внешние файлы, установлены неверно или если они указывают на ресурсы, которые по какой-то причине недоступны, программа генерирует ошибку. При использовании переменных, которые задают файлы, необходимо проверить, существуют ли эти файлы и имеют ли они соответствующие разрешения доступа.

Ошибки формата вывода

Последний тип ошибок, в отсутствии которых нужно убедиться перед вызовом программы из браузера, составляют ошибка формата вывода. Перед всей выходной информацией CGI-программы, предназначенной для Web-браузера посетителя ( т.е. перед всем, что выводится в STDOUT), должен идти правильный HTTP-заголовок, иначе будет сгенерирована ошибка «500 Server Error».

Например, если вы генерируете HTML-страницу, то первым выполняемым программой оператором print должен быть следующим:

Этот оператор выводит HTTP-заголовок, показывающий, что следующая за ним информация будет содержать HTML-страницу. Если вы не забудете в своей программе поставить эту строку (или соответствующий HTTP-заголовок при выводе не HTML-страницы) перед всеми остальными операторами print, то избежите любых ошибок формата вывода.

Ошибки в логике программы (использование Perl-отладчика)

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

Запуск отладчика

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

Флаг -d дает Perl указание включить отладчик. Вы получите несколько сообщений, за которыми следует приглашение отладчика, выглядящее примерно так:

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


Как получить помощь

Команды отладчика состоят из одного или двух символов, за которыми иногда следует необязательный или обязательный аргумент.

Полный список этих команд можно получить путем ввода буквы h на приглашении отладчика и нажатия клавиши Enter.

Пошаговое прохождение программы

Основные команды отладчика позволяют обрабатывать программу по одной строке за раз. Если ввести на приглашение отладчика команду s и нажать клавишу Enter, то Perl выполнит следующую строку программы и выдаст новое приглашение.

Если ввести команду n и нажать клавишу Enter, то Perl сделает то же самое, но пропустит вызовы подпрограмм. (Команда s вводит вас в подпрограмму). Если вы использовали любую из этих команд хотя бы один раз, то для повторного ее вызова нужно просто нажать клавишу Enter.

Просмотр значений

В любой момент работы с отладчиком вы можете проверить значения переменных, Для этой цели имеется несколько методов.

Ввод команды X и имени переменной (без спецификатора типа ( S, % или @) в начале) и последующее нажатие клавиши Enter заставят Perl выдать список переменных (используемых имя данной переменной) с их значениями в удобном формате. Это позволит вам увидеть содержимое массивов и ассоциативных массивов.

Можно также применить стандартный оператор print, например print $var__name. В принципе, по приглашению отладчика можно использовать любой допустимый оператор языка Perl.

Поиск строк

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

Эта команда заставит отладчик вывести на экран строку 180. Опустив номер строки, на экран можно вывести группу строк. Можно также вывести диапазон строк:

С помощью команды w можно вывести группу строк с текущей строкой или заданную строку в середине группы, чтобы поместить конкретную строку в контекст:

Эта команда выводит на экран группу строк со строкой 180 в середине. Если номер строки не указан, то используется номер текущей строки. Второй способ перехода в определенную точку программы — это стандартный поиск по образцу:

Эта команда ищет в программе следующий экземпляр переменной Scount и переходит в строку, которая его содержит. (Закрывающую косую можно опустить).

Точки останова

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

Эта команда заставляет программу сделать паузу, когда она дойдет до строки 180. (Для запуска программы или возобновления ее после прерывания служит команда с). Вы можете также задать условие, которое должно быть выполнено для того, чтобы программа прервалась. Например:

Следующая команда заставит программу прерваться на строке 180, если значение переменной Scount больше 5.

Удаление контрольных точек производится с помощью команд d (удаляется одна контрольная точка) и D (удаляются все контрольные точки):

Выполнение дополнительных команд

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

Эта команда заставит отладчик вывести текущее значение переменной $count непосредственно перед выполнением строки 180.

Отмена действий производится командой А (она отменяет все действия, которые вы установили для программы).

Имитация CGI-вызова

Perl-отладчик можно использовать с CGI-npoграммой. CGI-программы выполняются в удаленном режиме, поэтому доступа к отладчику не имеется. Тем не менее можно сымитировать CGI-вызов из самой программы, с тем чтобы с помощью отладчика следить за проблемами, возникающими только при CGI-вводе.

Установка переменных среды

Если ваша программа использует какие-либо переменные CGI-среды , то вы сможете модифицировать ассоциативный массив %ENV (Такие изменения носят временный характер и действуют на программу только тогда, когда она работает).

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

Имитация ввода данных формы

Еще одним элементом, нуждающимся в дублировании при имитации CGI-вызова, являются данные формы, которые передаются в программу. Если для передачи данных в форму используется метод GET, то сделать это достаточно легко. Метод передает данные формы в программу в переменной среды QUERY_STRING, поэтому нужно использовать что-нибудь похожее на две нижние строки приведенного выше примера.

При использовании метода POST ситуация усложняется лишь незначительно. Указанный метод передает в программу данные формы с помощью STDIN и задает количество передаваемых данных с помощью переменной среды CONTENT_LENGTH. Следовательно, для сбора данных можно использовать следующую CGI-программу:

Эта программа считает данные формы из STDIN, а потом запишет их в файл. Затем вы должны добавить в свою CGI-программу следующие строки:

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

Эти строки превращают запрос POST в запрос GET и считывают содержимое файла данных формы в переменную среды QUERY_STRING.

Как увидеть невидимое

Очень неприятен тот факт, что при выявлении логических ошибок в CGI-программе почти всегда генерируется сообщение «500 Server Error», которое ничего не скажет о происшедшем. Если программа генерирует ошибку «500», а вы не знаете почему, самый простой способ выявить проблему — заставить свой браузер вывести сообщение об ошибке.

Для этого нужно поставить следующие две строки в начало программы (сразу после строки #!/usr/bin/perl:

Первая строка дает Perl указание посылать всю выходную информацию прямо в браузер, не ожидая заполнения буфера. (Благодаря этому мы видим все, что выводит программа, и все, что выводит Perl в процессе выполнения программы).

Вторая строка сообщает браузеру о том, что все выводимое вашей программой в STDOUT должно рассматриваться как обычный текст и отображаться как таковой. Если эта строка есть, то при следующем вызове программы вы должны увидеть сообщение, которое приводит к выдаче сообщения об ошибке «500».

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

Так, если значение переменной $status должно быть равным 1, а вы подозреваете, что оно будет задано неверно, вставьте в точку, где эта переменная должна быть равной 1, следующую строку:

При следующем вызове программы вы увидите значение переменной $status у себя в браузере и сможете определить, в нем ли заключается причина возникшей проблемы. (По сути, вы выполняете в дистанционном режиме те же действия, которые обычно производятся в отладчике).

При более сложных ошибках этот метод работает достаточно медленно, но в отличие от других методов он все же работает.

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

Отладка CGI-скрипт, который не печатает HTML

Я хотел бы знать , как отладить cgi сценарий , который не выводит какой — либо HTML .

Я в настоящее время страницу входа в систему с html формой , что при представлении перенаправляет на другой cgi сценарий. Этот скрипт должен проверить, является ли пользователь введена правильной информации.

Этот сценарий не печатает из любого , html так что я не знаю , как я должен это проверить. Я в настоящее время приема , Internal Server Error когда перенаправление происходит с помощью этого сценария. В error.log гласит:

Может кто-то пожалуйста, скажите мне, как я могу отладить этот скрипт?

Спасибо за помощь.

Ошибка End of script output before headers: означает , что ваш скрипт закончил без вывода чего — либо. По сути, вы создали , CGI::Cookie но не послал его в браузер :

Если вы хотите установить куки, а затем перенаправляет на другую страницу, вы можете использовать:

Как я могу устранить неполадки моего скрипта Perl CGI?

У меня есть скрипт Perl, который не работает, и я не знаю, как начать сужать проблему. Что я могу сделать?

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

8 ответов

Этот ответ предназначен в качестве общей основы для работы через проблемы со сценариями Perl CGI и первоначально появились на Perlmonks как Устранение неполадок сценариев Perl CGI . Это не полное руководство для каждого проблема, с которой вы можете столкнуться, ни учебник по устранению ошибок. Это это только кульминация моего опыта отладки CGI-скриптов для двадцати (плюс! ) лет. На этой странице было много разных домов, и мне кажется, чтобы забыть, что он существует, поэтому я добавляю его в StackOverflow. Вы можете присылать мне любые комментарии или предложения по адресу bdfoy @ CPAN. орг. Это также вики сообщества, но не сходите с ума. :)

Используете ли вы встроенные функции Perl, чтобы помочь вам найти проблемы?

Включите предупреждения, чтобы Perl предупреждал вас о сомнительных частях вашего кода. Это можно сделать из командной строки с помощью переключателя -w , чтобы вам не приходилось изменять код или добавлять прагму к каждому файлу:

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

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

Сначала вы вывели правильный CGI-заголовок?

Сервер ожидает, что первый вывод из сценария CGI будет заголовком CGI. Обычно это может быть просто print «Content-type: text/plain\n\n»; или CGI. вечера и его производных, print header() . Некоторые серверы чувствительны к ошибкам (на STDERR ), которые отображаются перед стандартным выводом (на STDOUT ).

Попробуйте отправить ошибки в браузер

Добавить эту строку

к вашему сценарию. Это также отправляет ошибки компиляции в окно браузера. Обязательно удалите это, прежде чем переходить в производственную среду, так как дополнительная информация может представлять угрозу безопасности.

Что сказал журнал ошибок?

Серверы ведут журналы ошибок (или они должны, по крайней мере). Ошибка вывода с сервера и из вашего скрипта должна показать там. Найдите журнал ошибок и посмотрите, что он говорит. Там нет стандартного места для файлов журнала. Посмотри в Конфигурация сервера для их расположения, или спросите сервер админ. Вы также можете использовать такие инструменты, как CGI :: Carp сохранить свои собственные файлы журнала.

Каковы разрешения сценария?

Если вы видите ошибки, такие как «Отказано в доступе» или «Метод не разрешен» реализовано «, это, вероятно, означает, что ваш сценарий не читаемый и исполняемый пользователем веб-сервера. На вкус Unix, изменение режима на 755 рекомендуется: chmod 755 filename . Никогда не устанавливайте режим на 777!

Вы используете use strict ?

Помните, что Perl автоматически создает переменные, когда Вы сначала используете их. Это особенность, но иногда может вызвать ошибки, если вы неправильно набрали имя переменной. Прагма use strict поможет вам найти эти виды ошибки. Это раздражает, пока вы не привыкнете к этому, но ваш программирование значительно улучшится через некоторое время и Вы будете свободны делать разные ошибки.

Сценарий компилируется?

Вы можете проверить наличие ошибок компиляции, используя -c переключатель. Сконцентрируйтесь на первых зарегистрированных ошибках. Полоскание, повторение. Если вы получаете действительно странные ошибки, проверьте убедитесь, что ваш скрипт имеет правильные окончания строк. если ты FTP в двоичном режиме, извлечение из CVS или что-то еще, что не обрабатывает перевод конца строки, веб-сервер может видеть Ваш сценарий как одна большая строка. Перенести Perl-скрипты в ASCII Режим.

Сценарий жалуется на небезопасные зависимости?

Если ваш скрипт жалуется на небезопасные зависимости, вы Возможно, вы используете переключатель -T для включения режима загрязнения, который хорошая вещь, поскольку она позволяет передавать непроверенные данные в оболочку. Если он жалуется, что делает свою работу, чтобы помочь нам написать более безопасные сценарии. любой данные, поступающие извне программы (т.е. е. окружающая среда) считается испорченным Переменные среды, такие как PATH и LD_LIBRARY_PATH особенно хлопотно Вы должны установить их на безопасное значение или сбросьте их полностью, как я рекомендую. Вы должны использовать абсолют дорожки в любом случае. Если проверка порчи жалуется на что-то другое, убедитесь, что у вас нет данных. См. perlsec . Страница man для деталей.

Что происходит, когда вы запускаете его из командной строки?

Выводит ли скрипт то, что вы ожидаете при запуске из командная строка? Сначала выводится заголовок, а затем пустая строка? Помните, что STDERR могут быть объединены с STDOUT если вы находитесь на терминале (например, г. интерактивный сеанс), и из-за буферизации может отображаться в беспорядочном порядке. Включи Функция автоматического промывания Perl, установив $| в истинное значение Обычно вы можете увидеть $|++; в CGI программы. После установки, каждая печать и запись будет немедленно перейти к выводу, а не буферизироваться Вы должны установить это для каждого дескриптора файла. Используйте select для измените дескриптор файла по умолчанию, например:

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

Что происходит, когда вы запускаете его из командной строки в CGI-подобной среде?

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

Сброс или удаление этих переменных

  • PATH
  • LD_LIBRARY_PATH
  • все ORACLE_* переменные

Установите эти переменные

  • REQUEST_METHOD (установлен на GET , HEAD или POST в зависимости от ситуации)
  • SERVER_PORT (обычно 80)
  • REMOTE_USER (если вы делаете защищенный доступ)

Последние версии CGI.pm (& gt; 2. 75) требуется флаг -debug для получить старое (полезное) поведение, поэтому вам, возможно, придется добавить его в ваш CGI.pm импорт.

Вы используете die() или warn ?

Эти функции печатают до STDERR , если вы не переопределили их. Они также не выводят заголовок CGI. Ты можешь получить та же функциональность с такими пакетами, как CGI :: Carp

Что происходит после очистки кэша браузера?

Если вы считаете, что ваш скрипт работает правильно, и когда вы выполняете запрос вручную, вы получаете право Вывод, браузер может быть виновником. Очистить кеш и установите размер кеша равным нулю во время тестирования. Помни что некоторые браузеры действительно глупы и не будут перезагружаться новый контент, даже если вы скажете это сделать. Это особенно распространены в тех случаях, когда путь URL является то же самое, но содержание меняется (например, г. динамические изображения).

Это сценарий, где вы думаете, что это?

Путь файловой системы к сценарию не обязательно напрямую связан с URL-адресом пути к скрипту. Удостовериться у вас есть правильный каталог, даже если вам нужно написать короткий тестовый скрипт, чтобы проверить это. Кроме того, вы уверены, что вы модифицируете правильный файл? Если ты не видишь любой эффект с вашими изменениями, вы можете изменить другой файл или загрузка файла в неправильное место. (Это, кстати, моя самая частая причина таких неприятностей ;)

Используете ли вы CGI.pm или его производное?

Если ваша проблема связана с анализом ввода CGI, и вы не используются широко протестированные модули, такие как CGI.pm , CGI::Request , CGI::Simple или CGI::Lite , используйте модуль и продолжайте жить. CGI.pm имеет режим совместимости cgi-lib.pl , который может помочь вам решить ввод проблемы из-за более старых реализаций CGI-парсера.


Вы использовали абсолютные пути?

Если вы запускаете внешние команды с system , обратные тики или другие возможности IPC, Вы должны использовать абсолютный путь к внешней программе. Мало того, что вы точно знаете, что вы бежите, но вы также избегайте проблем с безопасностью. Если вы открываете файлы для чтения или записи, используйте абсолютный путь. Сценарий CGI может иметь другое представление о текущем Каталог, чем вы делаете. Кроме того, вы можете сделать явный chdir() , чтобы поставить вас в нужном месте.

Вы проверяли свои возвращаемые значения?

Большинство функций Perl сообщит вам, работали они или нет и установит $! при сбое. Вы проверили вернуть значение и проверить $! на наличие сообщений об ошибках? Ты проверил $@ , если вы использовали eval ?

Какую версию Perl вы используете?

Последняя стабильная версия Perl — 5. 28 (или нет, в зависимости от того, когда это последний раз редактировалось). Вы используете старую версию? Разные версии Perl могут иметь разные представления о предупреждениях.

Какой веб-сервер вы используете?

Различные серверы могут работать по-разному в одном и том же ситуация. Один и тот же серверный продукт может работать по-разному с разные конфигурации. Включите как можно больше этого информация, как вы можете в любой просьбе о помощи.

Вы проверили документацию сервера?

Серьезные программисты CGI должны знать как можно больше о сервер, насколько это возможно — включая не только функции сервера и поведение, но и локальная конфигурация. документация для вашего сервера может быть недоступна для вас если вы используете коммерческий продукт. В противном случае документация должна быть на вашем сервере. Если это не так, посмотрите для этого в Интернете.

Вы искали в архивах comp.infosystems.www.authoring.cgi ?

Это использование полезно, но все хорошие плакаты либо умерли, либо исчезли.

Вполне вероятно, что у кого-то была ваша проблема раньше, и что кто-то (возможно, я) ответил на это в этом телеконференция. Хотя эта новостная группа пережила свой расцвет, собранная мудрость прошлого иногда может оказаться полезной.

Можете ли вы воспроизвести проблему с помощью короткого тестового сценария?

В больших системах может быть трудно отследить ошибку поскольку так много всего происходит. Попробуйте воспроизвести проблему поведение с кратчайшим сценарием. Зная проблему это большая часть исправления. Это, конечно, может занять много времени, но вы еще не нашли проблему, и у вас заканчиваются варианты. :)

Вы решили пойти посмотреть фильм?

Серьезно. Иногда мы можем быть настолько погружены в проблему, что мы развить «сужение восприятия» (туннельное зрение). Сделать перерыв, выпить чашку кофе или убить плохих парней в [Duke Nukem, Quake, Doom, Halo, COD] может дать вам свежая перспектива, что вам нужно заново подойти к проблеме.

Вы озвучили проблему?

Снова серьезно. Иногда объясняю проблему вслух приводит нас к нашим собственным ответам. Поговорите с пингвином (плюшевая игрушка), потому что ваши коллеги не слушают. Если вы заинтересованы в этом как серьезный инструмент отладки (и я рекомендую его, если у вас нет обнаружил проблему сейчас), вы также можете прочитать Психология компьютерного программирования .

Я думаю, что стоит упомянуть CGI :: Debug .

Интересно, почему никто не упомянул опцию PERLDB_OPTS под названием RemotePort ; хотя по общему признанию, в Интернете не так много рабочих примеров ( RemotePort даже не упоминается в perldebug ) — и для меня было довольно проблематично придумать этот пример, но здесь это происходит (это пример Linux) ).

Чтобы сделать правильный пример, сначала мне нужно было кое-что, что может сделать очень простое моделирование веб-сервера CGI, предпочтительно с помощью одной командной строки. После нахождения простой веб-сервер командной строки для запуска cgis. (perlmonks. org) , я обнаружил, что IO :: All — Tiny Web Server подходит для этого теста.

Здесь я буду работать в каталоге /tmp ; сценарий CGI будет /tmp/test.pl (включен ниже). Обратите внимание, что сервер IO::All будет обслуживать только исполняемые файлы в том же каталоге, что и CGI, поэтому здесь требуется chmod +x test.pl . Итак, чтобы выполнить обычный тестовый запуск CGI, я изменяю каталог на /tmp в терминале и запускаю там однострочный веб-сервер:

Команда веб-сервера заблокирует в терминале и в противном случае запустит веб-сервер локально (на 127. 0. 0. 1 или localhost ) — после этого я могу зайти в веб-браузер и запросить этот адрес:

. , , и я должен наблюдать, как print , сделанные test.pl , загружаются — и показываются — в веб-браузере.

Теперь, чтобы отладить этот скрипт с помощью RemotePort , сначала нам понадобится слушатель 3230269583 в сети, через который мы будем взаимодействовать с отладчиком Perl; мы можем использовать инструмент командной строки netcat ( nc , видел здесь: Perl l удаленная отладка? ). Итак, сначала запустите приемник netcat в одном терминале, где он будет блокировать и ожидать подключения через порт 7234 (который будет нашим портом отладки):

Затем мы бы хотели запустить perl в режиме отладки с RemotePort , когда был вызван test.pl (даже в режиме CGI через сервер). В Linux это можно сделать с помощью следующего сценария «Оболочка Шебанга», который также должен быть в /tmp , и должен сделать исполняемым:

Это довольно сложно — см. Сценарий оболочки — Как я могу использовать переменные окружения в моем shebang? — Unix & amp; Linux Stack Exchange . Но уловка здесь, кажется, , а не для разветвления интерпретатора perl , который обрабатывает test.pl — поэтому, как только мы нажмем его, мы не сделаем exec , но вместо этого мы будем вызывать perl «просто», и в основном «источник» нашего сценария test.pl , используя do (см. Как запустить скрипт Perl из скрипта Perl? ).

Теперь, когда у нас есть perldbgcall.sh в /tmp — мы можем изменить файл test.pl , чтобы он ссылался на этот исполняемый файл в своей строке shebang (вместо обычного интерпретатора Perl) — здесь значение /tmp/test.pl изменено таким образом:

Теперь и test.pl , и его новый обработчик Шебанга, perldbgcall.sh , находятся в /tmp ; и у нас есть nc , прослушивающий отладочные соединения через порт 7234 — таким образом, мы можем наконец открыть другое окно терминала, изменить каталог на /tmp и запустить там однострочный веб-сервер (который будет прослушивать веб-соединения через порт 8080):

После того, как это будет сделано, мы можем зайти в наш веб-браузер и запросить тот же адрес, http://127.0.0.1:8080/test.pl . Однако теперь, когда веб-сервер пытается выполнить сценарий, он выполняет это посредством perldbgcall.sh Шебанга, который запустит perl в режиме удаленного отладчика. Таким образом, выполнение скрипта будет приостановлено — и поэтому веб-браузер заблокируется, ожидая данных. Теперь мы можем переключиться на терминал netcat , и мы должны увидеть знакомый текст отладчика Perl — однако вывод через nc :

Как показывает фрагмент, теперь мы в основном используем nc в качестве «терминала» — так что мы можем набрать r (и Enter) для «run» — и скрипт запустится, выполнив оператор точки останова (см. Также В Perl, что разница между $ DB :: single = 1 и 2? ), прежде чем снова остановиться (обратите внимание, что в этот момент браузер все еще будет блокироваться).

Итак, теперь мы можем, скажем, пройти через остаток test.pl через терминал nc :

. , , однако и на этом этапе браузер блокирует и ожидает данные. Только после выхода из отладчика с q :

. , , браузер останавливает блокировку — и, наконец, отображает (полный) вывод test.pl :

Конечно, этот вид отладки может быть выполнен даже без запуска веб-сервера — однако, здесь важно то, что мы вообще не касаемся веб-сервера; мы запускаем выполнение «нативно» (для CGI) из веб-браузера — и единственное изменение, которое необходимо в самом скрипте CGI, — это изменение shebang (и, конечно, наличие сценария-оболочки shebang как исполняемого файла в том же каталог).

Что ж, надеюсь, это кому-нибудь поможет — я уверен, что хотел бы наткнуться на это, а не писать сам :)
Ура!

die операторы и другие фатальные ошибки времени выполнения и компиляции получают напечатан на STDERR , который может быть трудно найти и может быть связан с сообщения с других веб-страниц на вашем сайте. Пока вы отлаживаете сценарий, это хорошая идея, чтобы фатальные сообщения об ошибках отображались в вашем браузер как-то.

Один из способов сделать это — позвонить

вверху вашего скрипта. Этот вызов установит обработчик $SIG <__die__>(см. perlvar ), отобразит фатальные ошибки в вашем браузере, добавив при необходимости действительный заголовок. Еще один прием отладки CGI, который я использовал до того, как услышал о CGI::Carp , был используйте eval со средствами DATA и __END__ в сценарии для обнаружения ошибок во время компиляции:

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

Обновление: Я никогда не использовал его, но похоже, CGI::Debug , как Mikael S предлагается, также является очень полезным и настраиваемым инструментом для этой цели.

Компьютерный портал osblog

Так сложилось, что я знаю как минимум двух человек, которые хотели бы выучить Perl. Специально для них я решил написать этот пост.

  • Часть 1: Типы переменных (вы читаете эту часть)

В нем вы найдете примеры простых программ из серии «вывести числа от 1 до 5» и тому подобное. Мне всегда нравилось учиться на примерах — это интереснее и быстрее, чем по книжкам или на семинарах. Также можете посмотреть посты этого блога, — велика вероятность, что в них вы найдете еще примеры.

Я предполагаю, что в школе/институте вы изучали Pascal/Delphi, C или хотя бы Basic, и объяснять, что такое функция и циклы не требуется. Если это не так — ничего страшного, просто для того, чтобы во всем разобраться, вам придется потратить лишнее время на чтение Википедии. Если вы не знаете, как запустить bash-скрипт, или для чего в первой строке скрипта писать что-то вроде #!/bin/sh , придется немного погуглить , чтобы это выяснить.

Специально для тех, кого интересуют вопросы, «а правда ли, что Perl очень сложен», «а какие книжки по Perl можете посоветовать» и даже «эээ… а что, на нем еще пишут?», я написал Mini-FAQ по Perl , которое вы можете прочитать на HabraHabr. А для тех, кто неасилил многабукв здесь я приведу краткое его содержание:

  • Perl — современный язык программирования, на котором пишут и будут писать еще очень долго.
  • Perl, как и любой другой язык программирования, имеет свои достоинства, недостатки и области применения. Существует действительно большой класс задач, которые Perl решает на 5+.
  • Синтаксис Perl не сложнее синтаксиса C++ или Java. В этом вы сможете убедиться, дочитав данный пост до конца.
  • Существуют хорошие и при этом недорогие учебники по Perl. Также в сети вы без труда найдете сообщество perl-программистов, говорящих на вашем родном языке.
  • Perl хорошо работает как под операционными системами семейства UNIX, так и под Злом Windows.

Дополнение: Также я рекомендую вам ознакомиться со статьями Perl vs Python vs Ruby vs PHP и Жрецы программирования . Первая повествует о производительности различных скриптовых языков, вторая — об отличии PHP от других ЯП. Фанатам Пайтона советую прочитать заметку Тест производительности скриптов на Python . Надеюсь, что эти материалы помогут вам найти ответ на вопрос «чем хорош Perl».

Привет, %username%!

Итак, давайте уже напишем наш первый скрипт на Perl!

$name = shift () ;
print («Hello, $name! \n » ) ;

$ chmod u+x 1 .pl
$ ./ 1 .pl afiskon
Hello, afiskon!

Тут все очень просто:

  • Имена скалярных переменных (то есть не массивов и не хэшей, что это такое — см ниже) начинаются со знака доллара.
  • Функция shift возвращает очередной аргумент скрипта. Другими словами первый вызов shift() возвращает первый аргумент, второй вызов — второй аргумент и так далее.
  • Функция print() выводит строку, переданную в качестве аргумента.
  • В строку можно подставлять значения переменных (см строку 4). Подробнее о строках — см далее.

Если пока не очень понятно — ничего страшного. Возможно, немного теории внесет чуть больше ясности.

Типы переменных

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

Скаляры мы уже использовали в предыдущем примере. Вот еще несколько примеров задания скаляров.

$a = 123 ;
$b = — 7.496 ;
$c = 0xABC; # равно 2748, да, это комментарий:)
$d = ($a + $b ) / $c ;
$d *= $a ; # тоже самое, что $d = $d * $a;

$str1 = «hello» ;
$str2 = «$str1, world» ; # в $str2 записано «hello, world»
$str3 = $a . » \n » . $str2 ;
$str4 = «$str1» ; # в $str4 записано «$str1», а не «hello»

Тут мы задаем положительные и отрицательные, целые и дробные числа, задаем число в шестнадцатеричной кодировке, складываем, умножаем и делим — все как в Си или Java. Кроме перечисленных операций Perl также поддерживает операцию возведения в степень:

$a = 2 ** 8 ; # результат: 256

Со строками все примерно так же, как в каком-нибудь PHP. Точка означает операцию конкатенации (то есть «склеивания» строк), если в строке содержатся имена переменных, на их место подставляются значения, с помощью обратного слэша можно вставлять символы новой строки (\n), табуляции (\t), кавычки (\»), сам обратный слэш (\\) знак доллара безо всякой подстановки переменных (\$) и многое другое. Если строка в одинарных кавычках, символы в ней трактуются «как есть», без подстановки переменных и тд.

Как и PHP, Perl интерпретирует скаляры, как числа или как строки в зависимости от операции. Все просто:

$int1 = «11» + 22 ;
# ^ строка «11» преобразуется в число,
# после чего выполняется сложение, результат: 33.
$str1 = «11» . 22 ;
# ^ число 22 преобразуется в строку,
# после чего выполняется конкатенация, результат: «1122».

Правила преобразования из строки в число и наоборот тут те же, что и в PHP:

$str1 = 0 . «abc» ;
# ^ результат — «abc», число ноль преобразуется в пустую строку
$int1 = «aaa» + 1 ;
# ^ результат — 1, в строке «aaa» нет цифр
$int2 = «12aaa» + 1 ;
# ^ результат — 13, учитываются только первые цифры строки

Кстати, для объявления длинных строк существуют специальные операторы — q и qq:

# аналогично одинарным кавычкам
$text = q <
Do you have $15 ?
> ;
# аналогично двойным кавычкам
$message = qq <
Hello, $username !
How are you?
> ;

Работа с массивами происходит следующим образом:

$scalar = «bebebebe» ;
($a , $b ) = (1 , 2 ) ; # тоже самое, что $a = 1; $b = 2;
@arr = («aaa» , 123 , $scalar , $a + $b ) ;
print $arr [ 1 ] . » \n » ;
push @arr , $a ;
print pop (@arr ) . » \n » ;

Здесь мы создаем массив @arr, состоящий из 4-х элементов (строка 5). Затем выводим второй элемент (строка 6). Нумерация элементов начинается с нуля, поэтому для вывода второго по счету элемента используется индекс 1. Затем кладем в конец массива значение переменной $a (функция push, строка 7), и тут же извлекаем и выводим его (функция pop, строка 8).

Обратите внимание, имена массивов начинаются с «собаки», а не доллара (запомнить не сложно — соответствующие символы похожи на первые буквы английских названий типов: $ — scalar, @ — array). При обращении ко второму элементу массива (строка 6) использовался знак доллара, потому что элемент массива является скаляром. По началу это вызывает много путаницы, но вообще все логично.

Еще в этом скрипте мы вызываем функции print и push без скобок. В Perl при вызове функции, везде, где это не вызывает неопределенности, скобки можно опустить.

Для объявления массива, элементами которого являются строки без пробелов, существует специальный оператор — qw:

@arr = qw/aaa bbb ccc/ ;
# аналогично («aaa», «bbb», «ccc»), только короче

Хэши похожи на массивы, но элементы в хэше не упорядочены. При этом в качестве ключа, по которому производится доступ к элементу, могут использоваться строки.

%hash = ( # при объявлении хэшей и массивов можно
«x» => 12 , # использовать перенос строк
y => 53 , # если в ключе нет спец-символов, кавычки не нужны
«z» => — 10.5 , # запятую на конце можно оставлять
) ;

$hash < "x" >++; # координата по x теперь равна 13
$hash < y >—; # координата по y теперь равна 52

# выводим координаты
print «x = $hash, y = $hash, z = $hash\n » ;

Имена хэшей начинаются со знака процента, для обращения к элементу используются фигурные скобки (а не квадратные, как в случае с массивами). Если имя ключа заранее известно, можно указывать его без кавычек (строка 10).

Кстати, переменные $test, @test и %test — это совершенно независимые друг от друга переменные разного типа.

В этом месте я хотел перейти к условным операторам и циклам for/while, но понял, что для одного поста текста и так уже многовато. Между тем за кадром остались многие вопросы:

  • Условные операторы;
  • Циклы for и while;
  • Объявление функций;
  • Работа с потоками и файлами;
  • Строгий синтаксис;
  • Использование готовых модулей и классов.

Об этом я напишу в одной из следующих заметок. Хотелось бы получить хотя бы парочку комментариев на этот пост — интересно/неинтересно, понятно/непонятно и так далее. Кстати, если у вас есть вопросы, связанные с Perl (не обязательно с этим постом) — смело задавайте их в комментариях!

Надеюсь, серия постов о программировании на Perl поможет вам написать ваши первые простенькие скрипты. Со временем скрипты будут становится сложнее, в них станут использоваться новые технологии (ООП, регулярные выражения) и через какое-то время вы обнаружите, что знаете о Perl достаточно, чтобы делиться опытом с другими.

Что такое Perl?

Perl является интерпретируемым языком, созданным программистом Лари Уоллом (Larry Wall) для обработки больших текстов и файлов и расшифровывается, как Practical Extraction and Report Language (язык для практического извлечения данных и составления отчетов). С помощью Perl вы, например, можете создать скрипт, который открывает один или несколько файлов, обрабатывает информацию и записывает результаты.

С изобретением World Wide Web, Perl оказался прекрасным средством для взаимодействия с web-серверами через Common Gateway Interface (CGI) — общий интерфейс взаимодействия. Команды Perl могут легко получить данные из формы HTML или другого источника и что-нибудь с ними сделать.

Как Perl обрабатывает данные из форм

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

  • добавить их в текстовый файл,
  • ввести их в базу данных,
  • вставить их в электронное письмо,
  • добавить их в существующую web-страницу,
  • создать новую web-страницу,
  • отобразить их в окне браузера.


Некоторые из этих примеров рассматриваются в нашем уроке.

Как генерируются web-страницы «на лету»

Больше всего впечатляет то, что Perl может быть использован для создания web-страниц «на лету» в ответ на запрос или действие пользователя. Новая страница может быть

  • благодарностью за заполнение формы
  • страницей подтверждения с возможностью редактирования
  • запросом дополнительных данных
  • результатом запроса к базе данных или запроса поиска

Эта возможность обеспечивает истинную интерактивность вашего узла. Такие скрипты позволят web-серверу автоматически реагировать на определенный набор запросов пользователя, предоставляя данные в требуемом пользователем виде.

В чем различие между программой и скриптом?

Перед началом работы с Perl необходимо понять разницу между программой и скриптом. Оба из них используют набор инструкций для выполнения определенного задания, но программа скомпилирована в эффективный двоичный формат, что позволяет ей быстро выполняться на определенной платформе, в то время как скрипт хранится в оригинальном текстовом формате.

За счет того, что скрипты значительно короче программ, они выполняются тоже достаточно быстро.

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

Альтернативы Perl

Существует несколько альтернатив использованию Perl:

  • С, Visual Basic — более традиционные компьютерные языки для обработки вводимых данных. Должны компилироваться под определенную платформу.
  • ActiveX — включение программных компонент, выполняющихся в браузере.
  • JavaScript, VBScript — обеспечивают некоторую интерактивность HTML страниц, которую HTML обеспечить не может.
  • Cold Fusion — сторонняя программа для связи форм с базами данных.
  • PHP/FI — еще одна сторонняя программа для связи форм с базами данных.

Несмотря на это Perl на сегодняшний день является наиболее простым и быстрым и в тоже время очень мощным средством придания интерактивности вашему узлу.

Что вам требуется, чтобы запустить Perl

Для запуска Perl вашей системе понадобится несколько компонент:

  1. Скрипт, написанный вами или предложенный вам другим, сохраненный в текстовом файле.
  2. Perl интерпретатор. Любой Perl скрипт в первой строке содержит путь к этой программе.
  3. Web-страница с которой будет запускаться этот скрипт. Она может содержать форму или просто ссылку, если скрипт не требует входных данных.
  4. Web-сервер. Взаимодействие между web-страницей и скриптом производится сервером. Поэтому вы должны иметь доступ к web-серверу с возможностью записи и запуска на нем скриптов.

Где взять Perl

Существует много различных мест, где можно получить информацию о последних версиях Perl.

  • Общая информация о Perl — http://www.perl.com/perl/index.html
  • Perl для UNIX — http://www.perl.com/perl/info/software.html
  • Perl для Win32 — http://ntperl.hip.com

Этапы создания скрипта

После того, как вы установили на своем компьютере необходимое ПО, нужно совершить несколько шагов для запуска Perl на вашем узле:

  1. Создать форму для вызова скрипта.
  2. Создать сам скрипт.
  3. Отладить скрипт. Проверить отсутствие ошибок (если это возможно, лучше проверить все возможные пути выполнения программы).
  4. Поместить скрипт на сервер и не забыть дать ему права на выполнение.
  5. Связать скрипт с формой, вставив его имя в параметр action тэга form. Например:

Компьютерный портал osblog

Так сложилось, что я знаю как минимум двух человек, которые хотели бы выучить Perl. Специально для них я решил написать этот пост.

  • Часть 1: Типы переменных (вы читаете эту часть)

В нем вы найдете примеры простых программ из серии «вывести числа от 1 до 5» и тому подобное. Мне всегда нравилось учиться на примерах — это интереснее и быстрее, чем по книжкам или на семинарах. Также можете посмотреть посты этого блога, — велика вероятность, что в них вы найдете еще примеры.

Я предполагаю, что в школе/институте вы изучали Pascal/Delphi, C или хотя бы Basic, и объяснять, что такое функция и циклы не требуется. Если это не так — ничего страшного, просто для того, чтобы во всем разобраться, вам придется потратить лишнее время на чтение Википедии. Если вы не знаете, как запустить bash-скрипт, или для чего в первой строке скрипта писать что-то вроде #!/bin/sh , придется немного погуглить , чтобы это выяснить.

Специально для тех, кого интересуют вопросы, «а правда ли, что Perl очень сложен», «а какие книжки по Perl можете посоветовать» и даже «эээ… а что, на нем еще пишут?», я написал Mini-FAQ по Perl , которое вы можете прочитать на HabraHabr. А для тех, кто неасилил многабукв здесь я приведу краткое его содержание:

  • Perl — современный язык программирования, на котором пишут и будут писать еще очень долго.
  • Perl, как и любой другой язык программирования, имеет свои достоинства, недостатки и области применения. Существует действительно большой класс задач, которые Perl решает на 5+.
  • Синтаксис Perl не сложнее синтаксиса C++ или Java. В этом вы сможете убедиться, дочитав данный пост до конца.
  • Существуют хорошие и при этом недорогие учебники по Perl. Также в сети вы без труда найдете сообщество perl-программистов, говорящих на вашем родном языке.
  • Perl хорошо работает как под операционными системами семейства UNIX, так и под Злом Windows.

Дополнение: Также я рекомендую вам ознакомиться со статьями Perl vs Python vs Ruby vs PHP и Жрецы программирования . Первая повествует о производительности различных скриптовых языков, вторая — об отличии PHP от других ЯП. Фанатам Пайтона советую прочитать заметку Тест производительности скриптов на Python . Надеюсь, что эти материалы помогут вам найти ответ на вопрос «чем хорош Perl».

Привет, %username%!

Итак, давайте уже напишем наш первый скрипт на Perl!

$name = shift () ;
print («Hello, $name! \n » ) ;

$ chmod u+x 1 .pl
$ ./ 1 .pl afiskon
Hello, afiskon!

Тут все очень просто:

  • Имена скалярных переменных (то есть не массивов и не хэшей, что это такое — см ниже) начинаются со знака доллара.
  • Функция shift возвращает очередной аргумент скрипта. Другими словами первый вызов shift() возвращает первый аргумент, второй вызов — второй аргумент и так далее.
  • Функция print() выводит строку, переданную в качестве аргумента.
  • В строку можно подставлять значения переменных (см строку 4). Подробнее о строках — см далее.

Если пока не очень понятно — ничего страшного. Возможно, немного теории внесет чуть больше ясности.

Типы переменных

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

Скаляры мы уже использовали в предыдущем примере. Вот еще несколько примеров задания скаляров.

$a = 123 ;
$b = — 7.496 ;
$c = 0xABC; # равно 2748, да, это комментарий:)
$d = ($a + $b ) / $c ;
$d *= $a ; # тоже самое, что $d = $d * $a;

$str1 = «hello» ;
$str2 = «$str1, world» ; # в $str2 записано «hello, world»
$str3 = $a . » \n » . $str2 ;
$str4 = «$str1» ; # в $str4 записано «$str1», а не «hello»

Тут мы задаем положительные и отрицательные, целые и дробные числа, задаем число в шестнадцатеричной кодировке, складываем, умножаем и делим — все как в Си или Java. Кроме перечисленных операций Perl также поддерживает операцию возведения в степень:

$a = 2 ** 8 ; # результат: 256

Со строками все примерно так же, как в каком-нибудь PHP. Точка означает операцию конкатенации (то есть «склеивания» строк), если в строке содержатся имена переменных, на их место подставляются значения, с помощью обратного слэша можно вставлять символы новой строки (\n), табуляции (\t), кавычки (\»), сам обратный слэш (\\) знак доллара безо всякой подстановки переменных (\$) и многое другое. Если строка в одинарных кавычках, символы в ней трактуются «как есть», без подстановки переменных и тд.

Как и PHP, Perl интерпретирует скаляры, как числа или как строки в зависимости от операции. Все просто:

$int1 = «11» + 22 ;
# ^ строка «11» преобразуется в число,
# после чего выполняется сложение, результат: 33.
$str1 = «11» . 22 ;
# ^ число 22 преобразуется в строку,
# после чего выполняется конкатенация, результат: «1122».

Правила преобразования из строки в число и наоборот тут те же, что и в PHP:

$str1 = 0 . «abc» ;
# ^ результат — «abc», число ноль преобразуется в пустую строку
$int1 = «aaa» + 1 ;
# ^ результат — 1, в строке «aaa» нет цифр
$int2 = «12aaa» + 1 ;
# ^ результат — 13, учитываются только первые цифры строки

Кстати, для объявления длинных строк существуют специальные операторы — q и qq:

# аналогично одинарным кавычкам
$text = q <
Do you have $15 ?
> ;
# аналогично двойным кавычкам
$message = qq <
Hello, $username !
How are you?
> ;

Работа с массивами происходит следующим образом:

$scalar = «bebebebe» ;
($a , $b ) = (1 , 2 ) ; # тоже самое, что $a = 1; $b = 2;
@arr = («aaa» , 123 , $scalar , $a + $b ) ;
print $arr [ 1 ] . » \n » ;
push @arr , $a ;
print pop (@arr ) . » \n » ;

Здесь мы создаем массив @arr, состоящий из 4-х элементов (строка 5). Затем выводим второй элемент (строка 6). Нумерация элементов начинается с нуля, поэтому для вывода второго по счету элемента используется индекс 1. Затем кладем в конец массива значение переменной $a (функция push, строка 7), и тут же извлекаем и выводим его (функция pop, строка 8).

Обратите внимание, имена массивов начинаются с «собаки», а не доллара (запомнить не сложно — соответствующие символы похожи на первые буквы английских названий типов: $ — scalar, @ — array). При обращении ко второму элементу массива (строка 6) использовался знак доллара, потому что элемент массива является скаляром. По началу это вызывает много путаницы, но вообще все логично.

Еще в этом скрипте мы вызываем функции print и push без скобок. В Perl при вызове функции, везде, где это не вызывает неопределенности, скобки можно опустить.

Для объявления массива, элементами которого являются строки без пробелов, существует специальный оператор — qw:

@arr = qw/aaa bbb ccc/ ;
# аналогично («aaa», «bbb», «ccc»), только короче

Хэши похожи на массивы, но элементы в хэше не упорядочены. При этом в качестве ключа, по которому производится доступ к элементу, могут использоваться строки.

%hash = ( # при объявлении хэшей и массивов можно
«x» => 12 , # использовать перенос строк
y => 53 , # если в ключе нет спец-символов, кавычки не нужны
«z» => — 10.5 , # запятую на конце можно оставлять
) ;

$hash < "x" >++; # координата по x теперь равна 13
$hash < y >—; # координата по y теперь равна 52

# выводим координаты
print «x = $hash, y = $hash, z = $hash\n » ;

Имена хэшей начинаются со знака процента, для обращения к элементу используются фигурные скобки (а не квадратные, как в случае с массивами). Если имя ключа заранее известно, можно указывать его без кавычек (строка 10).

Кстати, переменные $test, @test и %test — это совершенно независимые друг от друга переменные разного типа.

В этом месте я хотел перейти к условным операторам и циклам for/while, но понял, что для одного поста текста и так уже многовато. Между тем за кадром остались многие вопросы:

  • Условные операторы;
  • Циклы for и while;
  • Объявление функций;
  • Работа с потоками и файлами;
  • Строгий синтаксис;
  • Использование готовых модулей и классов.

Об этом я напишу в одной из следующих заметок. Хотелось бы получить хотя бы парочку комментариев на этот пост — интересно/неинтересно, понятно/непонятно и так далее. Кстати, если у вас есть вопросы, связанные с Perl (не обязательно с этим постом) — смело задавайте их в комментариях!

Надеюсь, серия постов о программировании на Perl поможет вам написать ваши первые простенькие скрипты. Со временем скрипты будут становится сложнее, в них станут использоваться новые технологии (ООП, регулярные выражения) и через какое-то время вы обнаружите, что знаете о Perl достаточно, чтобы делиться опытом с другими.

Что такое Perl?

Perl является интерпретируемым языком, созданным программистом Лари Уоллом (Larry Wall) для обработки больших текстов и файлов и расшифровывается, как Practical Extraction and Report Language (язык для практического извлечения данных и составления отчетов). С помощью Perl вы, например, можете создать скрипт, который открывает один или несколько файлов, обрабатывает информацию и записывает результаты.

С изобретением World Wide Web, Perl оказался прекрасным средством для взаимодействия с web-серверами через Common Gateway Interface (CGI) — общий интерфейс взаимодействия. Команды Perl могут легко получить данные из формы HTML или другого источника и что-нибудь с ними сделать.

Как Perl обрабатывает данные из форм

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

  • добавить их в текстовый файл,
  • ввести их в базу данных,
  • вставить их в электронное письмо,
  • добавить их в существующую web-страницу,
  • создать новую web-страницу,
  • отобразить их в окне браузера.

Некоторые из этих примеров рассматриваются в нашем уроке.

Как генерируются web-страницы «на лету»

Больше всего впечатляет то, что Perl может быть использован для создания web-страниц «на лету» в ответ на запрос или действие пользователя. Новая страница может быть

  • благодарностью за заполнение формы
  • страницей подтверждения с возможностью редактирования
  • запросом дополнительных данных
  • результатом запроса к базе данных или запроса поиска

Эта возможность обеспечивает истинную интерактивность вашего узла. Такие скрипты позволят web-серверу автоматически реагировать на определенный набор запросов пользователя, предоставляя данные в требуемом пользователем виде.

В чем различие между программой и скриптом?

Перед началом работы с Perl необходимо понять разницу между программой и скриптом. Оба из них используют набор инструкций для выполнения определенного задания, но программа скомпилирована в эффективный двоичный формат, что позволяет ей быстро выполняться на определенной платформе, в то время как скрипт хранится в оригинальном текстовом формате.

За счет того, что скрипты значительно короче программ, они выполняются тоже достаточно быстро.

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

Альтернативы Perl

Существует несколько альтернатив использованию Perl:

  • С, Visual Basic — более традиционные компьютерные языки для обработки вводимых данных. Должны компилироваться под определенную платформу.
  • ActiveX — включение программных компонент, выполняющихся в браузере.
  • JavaScript, VBScript — обеспечивают некоторую интерактивность HTML страниц, которую HTML обеспечить не может.
  • Cold Fusion — сторонняя программа для связи форм с базами данных.
  • PHP/FI — еще одна сторонняя программа для связи форм с базами данных.

Несмотря на это Perl на сегодняшний день является наиболее простым и быстрым и в тоже время очень мощным средством придания интерактивности вашему узлу.

Что вам требуется, чтобы запустить Perl

Для запуска Perl вашей системе понадобится несколько компонент:

  1. Скрипт, написанный вами или предложенный вам другим, сохраненный в текстовом файле.
  2. Perl интерпретатор. Любой Perl скрипт в первой строке содержит путь к этой программе.
  3. Web-страница с которой будет запускаться этот скрипт. Она может содержать форму или просто ссылку, если скрипт не требует входных данных.
  4. Web-сервер. Взаимодействие между web-страницей и скриптом производится сервером. Поэтому вы должны иметь доступ к web-серверу с возможностью записи и запуска на нем скриптов.

Где взять Perl

Существует много различных мест, где можно получить информацию о последних версиях Perl.

  • Общая информация о Perl — http://www.perl.com/perl/index.html
  • Perl для UNIX — http://www.perl.com/perl/info/software.html
  • Perl для Win32 — http://ntperl.hip.com

Этапы создания скрипта

После того, как вы установили на своем компьютере необходимое ПО, нужно совершить несколько шагов для запуска Perl на вашем узле:

  1. Создать форму для вызова скрипта.
  2. Создать сам скрипт.
  3. Отладить скрипт. Проверить отсутствие ошибок (если это возможно, лучше проверить все возможные пути выполнения программы).
  4. Поместить скрипт на сервер и не забыть дать ему права на выполнение.
  5. Связать скрипт с формой, вставив его имя в параметр action тэга form. Например:
Илон Маск рекомендует:  Загадочный тип pchar
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL