Опубликован: 15.08.2003 | Уровень: для всех | Доступ: платный | ВУЗ: Российский государственный гуманитарный университет
Лекция 2:

Введение в программирование CGI-скриптов и программирование скриптов на bash

< Лекция 1 || Лекция 2: 1234 || Лекция 3 >

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

Переменные окружения (оболочки) создаются в момент старта bash -скрипта. При этом существует два типа переменных — те, которые действуют только в данной оболочке, и те, которые наследуются извне. Для просмотра переменных окружения можно использовать команду set:

bash-2.01$ set
bash=/bin/bash
bash_versinfo=([0]="2" [1]="01" [2]="0" 
  [3]="1" [4]="release" 
  [5]="i386-pc-freebsd2.2.2")
bash_version='2.01.0(1)-release'
columns=106
dirstack=()
euid=1010
...

Здесь не приводится полный список всех переменных окружения. Показано только, как этот список отображается. Каждая переменная передается парой "имя=значение". При этом каждая такая пара записывается с новой строки. Попробуем распечатать все переменные окружения скрипта в виде HTML-таблицы, используя bash:

#!/usr/freeware/bin/bash
echo Content-type: text/html
echo
echo '<HTML><HEAD></HEAD><BODY>'
echo '<H1>переменные окружения</H1>'
echo '<TABLE BORDER=1>'
echo '<TR><TD>Имя</TD><TD>значение</TD></TR>'
IFS='='
set | while read x y
do
echo '<TR><TD>'$x'</TD><TD>'$y'</TD></TR>'
done
echo '</TABLE>'
echo '<HR>'
echo '</BODY></HTML>'

Первой командой echo формируется предложение HTTP-заголовка. Вторая команда echo обеспечивает пропуск строки между заголовком HTTP-сообщения и его телом. Затем начинает формироваться тело HTML-документа. Обратите внимание на прямые одинарные кавычки " ' ". Они применяются для того, чтобы защитить от интерпретации угловые скобки " < " и " > ", которые используются в bash для перенаправления стандартных потоков ввода/вывода.

Далее присваивается значение переменной окружения bash, которая не генерируется сервером HTTPIFS. Переменная IFS хранит список символов-разделителей слов. По умолчанию это пробел и табуляция. Но нам нужно разделить имя переменной и его значения, которые на самом деле разделены символом "=".

Теперь вызываем команду set. При этом ее стандартный поток вывода перенаправляем при помощи "|" команде read, которая считывает строку из стандартного ввода, при этом присваивая переменным x и y значения последовательно от начала строки выделенных слов. А слова мы разделяем символом "=".

Читаем стандартный ввод в цикле while условие do.... done. В качестве условия все та же команда read — если считываем данные, то "истина", если нет, то — "ложь". При этом внутри цикла выводим строки таблицы "имя — значение".

B конце скрипта приводим документ к стандартному виду HTML-документа.

Обратиться к значению переменной окружения можно, конечно, гораздо проще — по имени:

#!/usr/freeware/bin/bash
echo Content-type: text/html
echo
echo '<HTML><HEAD></HEAD><BODY>'
echo '<H1>QUERY_STRING</H1>'
echo QUERY_STRING = $QUERY_STRING
echo '<HR>'
echo '</BODY></HTML>'

Здесь по команде echo будет просто распечатано значение переменной окружения   QUERY_STRING.

Аргументы командной строки

Позиционные параметры или аргументы командной строки — это последовательность строковых констант, которые указываются в командной строке после имени скрипта. Любая встроенная в bash команда или команда Unix может запускаться с набором этих параметров. Например, для того, чтобы подсчитать число активных в данный момент процессов httpd, администратор систем выдает такую последовательность команд:

bash>ps -ax | grep httpd | wc -l

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

  • ps задана с аргументом -ax ;
  • grep задана с аргументом httpd ;
  • wc задана с аргументом -l.

Позиционные параметры (аргументы командной строки) задаются встроенными переменными $1$n, где n — число аргументов. Аргументы командной строки появляются при запросах типа ISINDEX. Число аргументов командной строки определяется встроенной переменной bash$#. Если мы вызовем скрипт по ссылке типа:

http://www.intuit.ru/cgi-bin/
  argv.cgi?arg1+arg2+arg3,

то переменная $# примет значение 3, а переменные: $1arg1, $2 arg2, $3arg3. Кстати, $0 — это имя самого скрипта. Распечатка параметров в виде HTML-таблицы может выглядеть следующим образом:

#!/usr/freeware/bin/bash
echo Content-type: text/html
echo
echo '<HTML><HEAD></HEAD><BODY>'
echo '<H1>Аргументы</H1>'
echo '<TABLE BORDER=1>'
echo '<TR><TH>Номер</TH><TH>Значение</TH></TR>'
let i=0
for x in $@
do
let i=i+1
echo '<TR><TD>arg['$i']</TD><TD>'$x'</TD></TR>'
done
echo '</TABLE>'
echo '</BODY></HTML>'

Последовательность команд echo формирует HTTP-сообщение. Команда let позволяет выполнять арифметические вычисления. Перед циклом for производим инициализацию переменной i. Цикл for "пробегает" по всем аргументам командной строки, которые объединены в переменной $@ и разделяются в ней пробелами. Фактически они представляют собой список слов, по которому и бежит переменная цикла x. Обратите внимание на отличие данного цикла от стандартного цикла for в С или Perl: в нем не используются арифметические операции, а идет работа со списком.

Внутри цикла при помощи команды let мы увеличиваем индекс аргумента командной строки (значение переменной i ) и распечатываем этот индекс и значение переменной x в виде элементов HTML-таблицы.

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

Стандартный поток ввода

По большому счету, для чтения данных из стандартного потока ввода в рамках программирования CGI-скриптов bash непригоден. Дело в том, что в нем нет механизма посимвольного считывания данных. Bash -скрипт способен читать только строками и останавливает считывание лишь в случае появления в потоке символа конца файла. Как известно, HTTP-сервер такого символа в стандартный поток ввода скрипта при работе по методу POST не передает. Тем не менее чтение стандартного ввода в рамках программирования CGI-скриптов на bash применяется.

Примером тому может служить генерация гипертекстовых ссылок на файлы текущего каталога:

#!/usr/freeware/bin/bash
echo Content-type: text/html
echo
echo '<HTML><HEAD></HEAD><BODY>'
echo '<Ul>'
ls -a | while read x
do
if test -f $x; then
echo '<LI><A HREF=./'$x'>'$x'</A>';
fi
done
echo '</BODY></HTML>'

В данном случае команда ls доставляет в скрипт имена файлов. Один файл — это отдельная строка. Эти имена обрамляются гипертекстовыми ссылками и вставляются в HTML-страницу. При этом печатаются только обычные файлы, все остальные игнорируются.

Другой пример — фильтрация. При приеме по методу GET запрос размещается в переменной QUERY_STRING. Но он там находится в форме form-urlencoded. Для его фильтрации вызывается внешняя программа, стандартный вывод которой перенаправляется на стандартный ввод одной из команд скрипта:

echo $QUERY_STRING | tr '+' ' ' | while read x
do
for y in $x
do
echo $y
done
done

Существуют и другие способы применения чтения из стандартного ввода при программировании CGI-скриптов на BASH.

< Лекция 1 || Лекция 2: 1234 || Лекция 3 >
Екатерина Cколова
Екатерина Cколова
Россия, Москва
Dima Semenchenok
Dima Semenchenok
Россия