Россия |
Введение в программирование CGI-скриптов и программирование скриптов на bash
Типы данных и переменные
В bash существует только два типа данных: скаляры и одномерные массивы. При этом возможно вычисление арифметических выражений, результат выполнения которых становится значением скаляра. По-другому эти типы можно интерпретировать как текстовые строки и списки.
Существует два типа переменных: встроенные переменные bash и переменные, определяемые пользователем (переменные пользователя). Не перечисляя всех встроенных переменных, назовем наиболее употребительные:
$1-$n — аргументы командной строки скрипта; $0 — имя скрипта; $@ — список аргументов командной строки; $# — число аргументов командной строки; $IFS — список разделителей; $PATH — путь поиска команд.
Переменные окружения, которые генерируются сервером — это переменные пользователя, импортируемые скриптом при его запуске. Пользователь внутри скрипта может установить собственные переменные:
IFS="="
В данном случае мы отменили значение по умолчанию для списка разделителей и назначили в качестве разделителя знак равенства "=". IFS — это глобальная переменная, поэтому она передается от скрипта к скрипту по умолчанию. Если требуется назначить собственную переменную и передать ее в другой скрипт, который вызывается из текущего скрипта, ее нужно будет экспортировать:
bash>QUERY_STRING=arg1+arg2+arg3; export QUERY_STRING
В данном случае в целях отладки скрипта в командной строке bash определена переменная окружения QUERY_STRING. Если запустить скрипт без предварительного экспорта, то значение этой переменной ( $QUERY_STRING ) будет неопределенным. Команда export позволяет передать это значение в тестируемый скрипт.
Управление потоком вычислений
Изо всех возможностей управления порядком выполнения команд в bash -скрипте мы рассмотрим только if, while и for. Пользуясь этими встроенными возможностями bash, следует иметь в виду, что логические выражения, которые применяются в качестве условий данных команд, строятся вокруг строк, а не чисел. Использовать числовое условие в bash крайне затруднительно.
if
Команда if имеет вид:
if list; then list; [elif list; then list;] ...[ else list;] fi
Сначала выполняется список команд, который стоит после if. Если он завершился успешно, то выполняется список команд после первого then. Значение и логика выполнения других частей этой команды очевидна. Команда начинается символами "if" и должна закончиться символами "fi". Часть команды в квадратных скобках — это необязательные конструкции, которые при необходимости можно опустить.
Рассмотрим в качестве примера проверку метода доступа к скрипту. Для bash это может быть только GET:
#!/usr/freeware/bin/bash echo Content-type: text/plain echo if test $REQUEST_METHOD = "POST"; then echo POST; elif test $REQUEST_METHOD = "GET"; then echo GET; else echo Unknown method $REQUEST_METHOD; fi
В данном случае мы используем сравнение строк (символ "="). Если нужно сравнивать арифметические выражения, то следует использовать другие операции сравнения:
-eq — равенство операндов; -ne — неравенство операндов; -lt — первый операнд меньше второго; -le — первый операнд меньше либо равен второму; -gt — первый операнд больше второго; -ge — первый операнд больше либо равен второму.
Команда test чрезвычайно полезна при работе с файловой системой. Например, при проверке наличия файла и прав на чтение можно использовать следующую комбинацию:
if test -r file.txt; then echo file.txt is readable; fi
Помимо проверки наличия файла и прав можно определять тип файла ( -d — каталог, -f — обычный файл и т.п.).
while
Команда while позволяет выполнять список команд до тех пор, пока справедливо условие использования данного списка, которое задается аргументом while. Чаще всего в наших примерах эта команда применяется при фильтрации входного потока:
ps -axj | grep httpd | while read id pid do if test $id = "root"; then kill -1 $pid; fi done
В данном случае в системе FreeBSD просматривается список активных процессов с именем httpd (HTTP-сервера), отыскивается процесс-родитель и перезапускается.
for
Вид команды for в bash отличается от обычного; когда в команде инициализируется переменная цикла, происходит проверка условия для переменной цикла и производится изменение ее значения. В bash переменная бежит по списку и выполняет цикл до тех пор, пока список не будет исчерпан:
for var; in list; do list; done
Переменная var принимает значения из списка, указанного за in, до тех пор, пока этот список не кончится. При этом для каждого значения var выполняется список команд, заключенный между "do" и "done". Примером использования for может служить разбор входных строк:
ls -ax | while read x do for y in $x do echo $y done done
Считываемая из стандартного ввода строка разбивается на слова, и каждое слово печатается отдельно на новой строке.