Текст книги "Linux и UNIX: программирование в shell. Руководство разработчика"
Автор книги: Дэвид Тейнсли
сообщить о нарушении
Текущая страница: 24 (всего у книги 25 страниц)
Для отсылки данных в качестве типа ввода указывается слово submit. Чтобы очистить форму, щелкните на кнопке clear.
Введите следующий сценарий cgi, назовите его books_result.cgi и сохраните его в каталоге cgi‑bin.
$ pg books_result.cgi
#!/bin/sh
#сценарий books_result.cgi
#вывод на печать настроек web–сервера env для метода get
echo "Content‑type: text/html"
echo ""
echo "
""echo "
""echo " Results from a GET form"
echo "REQUEST_METHOD : $REQUEST_METHOD"
echo "QUERY STRING : $QUERY_STRING"
echо "
Сценарий отображает значения пары переменных cgi, query_strinG и request_method. Переменная Query_string будет хранить все данные в виде кодированной строки, которая отправлена формой, созданной с помощью сценария books.cgi. Переменная request_method сохраняет тип используемого метода; в данном случае будет выбран метод get. На рис. 29.7 показано, как выглядит форма, созданная с помощью сценария books.cgi.
Рис. 29.7. Форма cgi, использующая метод get
Теперь выполним ввод и отсылку некоторой информации (рис. 29.8). После щелчка на кнопке 'Send it' отображается страница, показанная на рис. 29.9. Значение переменной QUERY_string отображается только частично по причине большой длины строки. Ниже приведена строка, имеющая полную длину:
contact=David+Tansley&f ilm=The+So_md+Of+Music&actor=Bruce+Willis&view_cine=onS,view_vid=onbtextarea=%21%22%A3%A3%24%25 %24%25%5E*%5E%26*%28%29*%2 8%29%28*%OD%OAHow%27s+that+%21%21
Рис. 29.8. Выбор и ввод информации в форму
Рис. 29.9. Информация, отправленная формой, закодирована
Для пересланной информации необходимо иметь следующие поля, присвоенные
переменной query string, показанной выше:
Переменная
Значение переменной
contact
David Tan$1ey
film
The Sound of Music
actor
Bruce Willis
view cine
Если установлено значение on, то флажок выбран
view_vid
Если установлено значение on, то флажок выбран
textarea
!"%$%А*А&*о*о(*
How's that it!
Декодирование закодированной строки
После того как пользователь щелкнет на кнопке "submit", информация присваивается переменной query_string, а строка кодируется следующим образом: • Все пробелы заменяются знаками +.
• Все поля значений разделяются символами &.
• Все значения и соответствующие поля разделяются знаками =.
• Все символы и некоторые специальные символы представляются кодами %ху, где xy является шестнадцатеричным эквивалентом данного символа. При просмотре переменной QUERY_STRING можно заметить, что многие из этих символов представлены переменной textarea.
Протокол cgi определяет, что любые символы в форме %ху (где xy является шестнадцатеричным числом) могут быть преобразованы в эквивалентные символы ASCII. Эти шестнадцатеричные символы состоят из специальных символов &, %, +, =, (, ) и всех других символов, выходящих за рамки десятичного диапазона ASCII с границей 127. Например, символу ( соответствует эквивалент в виде %29.
Шестнадцатеричные символы создаются в том случае, когда пользователь вводит значения в свободные текстовые поля. Однако эти символы могут также являться частью выбранного текста меню. Для выполнения декодирования закодированной строки нужно выполнить следующее:
• заменить все символы & символами перевода строки;
• заменить все символы + пробелами;
• заменить все символы = пробелами;
• преобразовать все значения %xy в эквивалентные символы ASCII.
После завершения описанной выше последовательности действий должна быть возможность осуществить запрос или реализовать доступ к каждой переменной. Благодаря этому можно обрабатывать отсылаемую информацию. В ходе декодирования выполняется только половина работы, хотя и наиболее трудоемкая. Для обеспечения доступа к значениям переменных можно воспользоваться командой eval.
Следующий сценарий выполняет все необходимые преобразования, а также обеспечивает доступ к переменным. Сценарий снабжен множеством комментариев, поэтому разобраться в его работе не составит особого труда.
$ pg conv.cgi
#!/bin/sh
#сценарий conv.cgi
#декодирование строки URL
echo "Content‑type: text/html"
echo ""
echo "
""#отображение метода кодированной строки
echo "Method : $REQUEST_METHOD"
echo "Query String : $QUERY_STRING"
echo "
"#применение редактора sed для замены символов & символами табуляции
LINE=`echo $QUERY_STRING | sed 's/&/ /g'`
for LOOP in $LINE do
# разбивка на поля NAME и TYPE
NAME=`echo $LOOP | sed 's/=/ /g' | awk '{print $1}'`
#получение TYPE, замена всех символов=пробелами, a %hex_num – xhex_num
#замена всех символов + пробелами
TYPE=`echo $LOOP | sed 's/=/ /g' | awk '{print $2}' | sed -e 's/%()/\x/g' | sed 's/+/ /g'`
#используется функция printf, которая отображает значения переменных:
#после завершения преобразований шестнадцатеричных значений
printf "${NAME}=${TYPE}n"
#в переменную VARS записываются значения отдельных полей, которые затем
#передаются команде eval, благодаря чему отдельные поля можно адресовать;
#при этом, если поля содержат пробелы, требуется удвоенная обратная косая черта
VARS=`printf "${NAME}=\${TYPE}n"`
eval `printf $VARS`
done
echo "
"#используется printf для отображения специальных символов в случае их наличия
printf "Your name is : $contactn"
printf "Your choice of film is : $filmn"
printf "Your choice of actor is : $actorn"
printf "You watch films at the cinema : $view_cinen"
printf "You watch films on video : $view_vidn"
printf "And here are your comments : $textarean"
echo "
echo ""
Нетрудно заметить, что в данном случае используется функция printf для вывода данных на экран. Причина этому весьма проста. Функция printf выполняет те же действия, что и обычная команда echo, но дополнительно выполняет шестнадцатеричные преобразования. В связи с этим следует сделать небольшое замечание. При использовании функции printf не происходит вставка символа новой строки; для устранения этого недостатка необходимо после каждой функции printf указать символы "n", Шестнадцатеричные числа, хранящиеся в переменной QUERY_STRING, имеют формат %hex_num. Этот формат будет просто преобразован в формат xhex_num с помощью потокового редактора sed, а также функции printf, выполняющей все необходимые преобразования. Зачем создавать себе дополнительные трудности, если для решения задачи существует простой способ?
Сохраните указанный выше сценарий под именем conv.cgi в каталоге cgi‑bin. Теперь осталось выполнить небольшое изменение в сценарии books.cgi, в результате чего форма будет вызывать сценарий conv.cgi вместо сценария books_result.cgi. Для этого следует воспользоваться следующей строкой:
echo ""
echo ""
Переменной dept присваивается выбранное значение для отдела; переменной qtr присваивается номер выбранного квартала. Переменной stdout присваивается значение "printer", "screen" или "both"; в качестве значения по умолчанию выбирается screen (это значение указывается с помощью слова "CHECKED"). Ниже приведен сценарий, обрабатывающий полученную информацию.
$ pg gifts_result.cgi
#!/bin/sh
#сценарий gifts_result.cgi
#Декодирование строки URL
еcho "Content‑type: text/html"
echo ""
echo "
""# это post ???
if [ "$REQUEST_METH0D" = "POST" ]; then
QUERY_STRING=`cat -`
fi
# декодирование
# используется sed для замены & символом табуляции
LINE=`echo $QUERY_STRING | sed 's/&/ /g'`
for LOOP in $LINE
do
NAME=`echo $LOOP | sed 's/=/ /g' | awk '{print $1}'`
TYPE='echo $LOOP | sed 's/=/ /g' | awk '{print $2}' |
sed -e 's/%()/\x/g' | sed 's/+/ /g'`
# используется printf при выполнении шестнадцатеричных преобразований VARS=`printf "${NAME}=\${TYPE}n"`
eval `printf $VARS`
done
echo "
"echo "
GIFTS Inc "echo "
"
Quarter End Results echo "
"#нужно изменить имена полей со STATIONERY на STAT
#для осуществления корректного поиска
if [ "$DEPT"="STATIONERY" ]; then
dept=STAT
fi
# считывание из файла qtr_1995.txt
TOTAL=0
while read DEPT YEAR Q P1 P2 Р3 Р4
do
if [ "$DEPT"="$DEPT" -a "$Q"="$qtr" ]; then
TOTAL=`expr $P1 + $P2 + $P3 + $P4`
fi
continue
done
echo "
"
echo " TOTAL ITEMS SOLD IN THE $DEPT DEPARTMENT"
echo "is $TOTAL IN THE $qtr QUARTER"
echo "
"# куда будет выведен отчет
if [ "$stdout"="Both" ]; then
echo "This report ls going to the printer and the screen"
else
echo " This report ls going to the $stdout"
fi
echo "
echo ""
Первая часть сценария является общей для любой формы, обработка которой осуществляется с помощью метода post. Поскольку отсутствуют шестнадцатеричные значения для преобразования (так как поля ввода являются предопределенными опциями меню), нет нужды в использовании функции printf, но особого смысла в том, чтобы отказаться от использования этой команды, нет. Содержательная часть сценария выполняет считывание из файла qtr_1995.txt.
Цикл while осуществляет считывание и присваивание значений полей переменным dept, year, q, p1, Р2, P3, Р4 соответственно. Затем выполняется проверка значения переменной $dept (значение, отправленное пользователем) и переменной dept; результат конкатенируется с результатом другой проверки с помощью оператора AND. Если значение переменной $qtr (значение, отосланное пользователем) равно значению переменной Q, имеет место соответствие. Все числа, содержащиеся в сравниваемой строке, добавляются вместе.
В настоящее время в нашем распоряжении имеется сценарий формы и сценарий, предназначенный для обработки информации, пересылаемой формой (запустите этот сценарий). Введите URL (либо создайте соответствующую ссылку на главной странице):
http://<имя_сервера>/cgi‑bin/gifts.cgi
Результаты показаны на рис 29.13.
Рис. 29.13. Выборка квартальной информации для дальнейшей обработки
Сценарий обрабатывает информацию, выбранную пользователем, и генерирует вывод, показанный на рис. 29.14.
Рис. 29.14. Обработка завершена, вывод результатов
29.5.3. Заполнение списка
Если HTML–страницы являются действительно динамическими, следует предусмотреть возможность заполнения списков или таблицы текущими данными, выбранными из существующего файла, вместо того, чтобы жестко кодировать эти данные в сценариях cgi.
Следующий сценарий реализует заполнение раскрывающегося списка данными, содержащимися в текстовом файле list Этот файл находится во временном каталоге, но не в корневом каталоге web–сервера. Цикл while используется для считывания содержимого (построчно( из файла. Для заполнения списка используется следующий кода:
echo "
Выбранный элемент присваивается переменной menu_selection. Ниже приводится сценарий, заполняющий элементы меню; действие формы не указывается.
$ pg populat.cgi
#!/bin/sh
#сценарий populat.cgi
#заполнение раскрывающегося списка значениями из текстового файла
echo "Content‑type: text/html"
echo ""
echo ""
echo "
"echo "
CGI FORM….populat.cgi..populate pull‑down list from a text
file"
echo "
echo "
# считывание значений из файла для заполнения опций списка
while read LINE
do
echo "
echo ""
echo ""
echo ""
echo ""
29.5.4. Автоматическое обновление Web–страницы
При использовании cgi для программирования заданий, выполняющих функции мониторинга либо контроля, часто бывает удобно выполнять обновление страниц в непрерывном режиме. Для этого вызывается пользовательский сценарий или страница. Ниже приводится тег, вызывающий выполнение сценария dfspace.cgi каждые 60 секунд.
"
Здесь ключевым словом является слово Refresh. Благодаря его использованию Web–сервер получает сведения о загрузке данной страницы, а строка "content=60" задает время (в секундах( между повторными загрузками. Для обновления сценария просто добавьте имя сценария в качестве части адреса URL.
В распоряжении автора имеются несколько контролирующих сценариев, выполняющих опрос всех основных хостов в сети. Благодаря их применению можно сразу же определить, какие хосты выполняются, а какие -oтключены. Более симпатичный вид сценарию придает использование в тексте вместо опций on и off зеленых и красных шариков.
Ниже приводится сценарий, использующий часть вывода df и отображающий файловую систему и количество полей в таблице.
Следующий сегмент кода реализует заголовок таблицы, в который помещаются наименования колонок. При использовании таблиц с неотформатированным выводом может происходить потеря данных.
echo "
– Capacity % - | "– File System - | "
---|---|
$percent | $mount |
– Capacity % - | "– File System - | "
---|
$percent$mount |
echo ""
При вводе URL
http://<имя_сервера>/cgi‑bin/dfspace.cgi
в окне броузера отображается вывод, показанный на рис. 29.15. В вашем случае могут наблюдаться отличия.
Рис. 29.15. Использование вывода команды df для генерирования таблиц
29.6. Заключение
Сценарии cgi обеспечивают создание весьма привлекательного пользовательского интерфейса. Страницы HTML могут использоваться в качестве интерфейса для всех распространенных задач, выполняющих обработку информации.
Создаваемые сценарии могут применяться для мониторинга, создания интерфейса, запросов к базам данных и решения других задач. Язык HTML является стандартным форматом для создания документации, поставляемой вместе с программным обеспечением.
ПРИЛОЖЕНИЕ А Коды ASCII
Символ
Десятичное значение
Шестнадцатеричное значение
Восьмеричное
значение
Ctrl-@
(NUL)
0
00
000
Ctrl‑A
1
01
001
Ctrl‑B
2
02
002
Ctrl‑C
3
03
003
Ctrl‑D
(EOT)
4
04
004
Ctrl‑E
5
05
005
Ctrl‑F
6
06
006
Ctrl‑G
(BEL)
7
07
007
Ctrl‑H
(BS)
8
08
010
Ctrl‑I
(TAB)
9
09
011
Ctrl‑J
(NL)
10
0А
012
Ctrl‑K
11
0B
013
Ctrl‑L
(FF)
12
0C
014
Ctrl~M
(CR)
13
0D
015
Ctrl‑N
14
0Е
016
Ctrl‑O
15
0F
017
Ctrl‑P
16
10
020
Ctrl‑Q
17
11
021
Ctrl‑R
18
12
022
Ctrl‑S
19
13
023
Ctrl‑T
20
14
024
Ctrl‑U
21
15
025
Ctrl‑V
22
16
026
Ctrl‑W
23
17
027
Ctrl‑X
24
18
030
Ctrl‑Y
25
19
031
Символ
Десятичное значение
Шестнадцатеричное значение
Восьмеричное
значение
Ctrl‑Z
26
1A
032
Ctrl -[ (ESC)
27
1B
033
Ctrl-
28
1С
034
Ctrl-]
29
1D
035
Ctrl-^
30
1E
036
Ctrl-_
31
1F
037
Пробел
32
20
040
;
33
21
041
"
34
22
042
#
35
23
043
$
36
24
044
%
37
25
045
&
38
26
046
'
39
27
047
(
40
28
050
)
41
29
051
*
42
2A
052
+
43
2B
053
`
44
2C
054
_
45
2D
055
.
46
2E
056
/
47
2F
057
0
48
30
060
1
49
31
061
2
50
32
062
3
51
33
063
4
52
34
064
5
53
35
065
6
54
36
066
7
55
37
067
8
56
38
070
9
57
39
071
:
58
ЗА
072
!
59
3B
073
<
60
3C
074
Символ
Десятичное
Шестнадцатеричное значение
Восьмеричное значение
значение
=
61
3D
075
>
62
3E
076
?
63
3F
077
@
64
40
100
А
65
41
101
в
66
42
102
с
67
43
103
D
68
44
104
E
69
45
105
F
70
46
106
G
71
47
107
Н
72
48
110
I
73
49
111
J
74
4А
112
К
75
4В
113
L '
76
4С
114
M
77
4D
115
N
78
4Е
116
0
79
4F
117
P
80
50
120
Q
81
51
121
R
82
52
122
S
83
53
123
т
84
54
124
U
85
55
125
V
86
56
126
W
87
57
127
X
88
58
130
Y
89
59
131
Z
90
5А
132
[
91
5В
133
92
5С
134
]
93
5D
135
^
94
5Е
136
95
5F
137
Символ
Десятичное значение
Шестнадцатеричное значение
Восьмеричное значение
`
96
60
140
а
97
61
141
b
98
62
142
с
99
63
143
d
100
64
144
e
101
65
145
f
102
66
146
Я
103
67
147
h
104
68
150
i
105
69
151
j
106
6А
152
k
107
6В
153
1
108
6С
154
m
109
6D
155
n
110
6Е
156
0
111
6F
157
p
112
70
160
q
113
71
161
r
114
72
162
s
115
73
163
t
116
74
164
u
117
75
165
V
118
76
166
w
119
77
167
X
120
78
170
у
121
79
171
z
122
7А
172
{
123
7В
173
|
124
7С
174
}
125
7D
175
~
126
7Е
176
Ctrl-? (DEL) 127
7F
177
ПРИЛОЖЕНИЕ Б
Полезные команды интерпретатора shell
В этом приложении перечисляются и описываются некоторые полезные команды интерпретатора shell. Здесь не приводится исчерпывающий список параметров для каждой команды. Однако имеющихся параметров вполне достаточно для понимания работы команд.
Дополнительные примеры использования можно найти в других главах книги.
basename
Формат:
basename путь
Команда basename выделяет путь из имеющегося имени пути и просто возвращает имя файла. Эта команда обычно применяется в конструкциях usage в сценариях. В этом случае подстановка используется при отображении на экране имен файлов.
$ basename /home/dave/myscript
myscript
echo "Usage: `basename $0` give me a file" exit 1
Если приведенный выше код именуется myscript, вывод может быть следующим:
myscript: give me a file
Здесь $0 является специальной переменной, которой присвоено текущее полное имя пути для сценария.
cat
Формат:
cat параметры файлы
Параметры:
–v Задается отображение управляющих символов
Команда cat является одной из наиболее часто применяемых команд постраничной разбивки текстовых файлов.
$ cat myfile
Отображение содержимого файла myfile.
$ cat myfile myfile2 >> hold_file
Приведенная выше команда осуществляет объединение двух файлов (myfile и myfile2) в один файл, именуемый hold_file.
cat dtl | while read line do
echo $LINE done
Команда cat также используется для считывания файлов, осуществляемого с помощью сценариев.
compress
Формат:
compress параметры файлы
Параметры:
–v Вывод на экран результатов сжатия
Команда compress используется для уменьшения размера файлов. После завершения сжатия файл получает расширение .Z Для возврата файла в исходное состояние используется команда uncompress.
$ compress myfile
$ ls myfile*
myfile. Z
cp
Формат:
cp параметры файл1 файл2
Параметры:
–i Запрос на подтверждение перезаписи файлов
–p Сохранение набора прав доступа и времени изменения
–r Рекурсивное копирование каталога
Для копирования файла myfile в myfilel.bak применяется команда:
$ cp myfile1 myfile1.bak
Копирование файла get.prd из каталога /usr/local/sybin в каталог /usr/local/bin осуществляется командой
$ pwd
/usr/local/sybin
$ cp get.prd ../bin
Для рекурсивного копирования всех файлов и подкаталогов из каталога /logs (вниз) в каталог /hold/logs применяется команда:
$ cp -r /logs/ /hold/logs
diff
Формат:
diff параметры файл1 файл2
Параметры:
–c Генерирует различный вывод на основе стандартного формата (см. ниже) – i Игнорирование регистров символов
При использовании файлов файлы файл2 из нашего примера comm команда diff будет выводить строки, которые не совпадают в заданных файлах.
$ diff файл1 файл2
2,3с2,3
>The games >The boys in company С Команда diff сообщает о том, что строки 2 и 3 различны, но второй столбец в строке 3 не совпадает. dircmp Формат: dircmp параметры каталог1 каталог2 Параметры: –s Не отображать различные файлы Действие команды dircmp напоминает действие команды diff: она также производит сравнение с последующим выводом на экран найденных различий. dirname Формат: dirname имя_пути В противоположность команде basename, команда dirname выводит на экран только имя пути: $ dirname /home/dave/myfile/home/dave du Формат: du параметры каталог Параметры: –a Отображается размер каждого файла, а не только размер каталогов -s Отображается только итоговая сумма Команда du выводит информацию об использовании диска в виде блоков размером по 512 байтов. Эта команда применяется, главным образом, для вывода размеров каталогов. $ pwd /var $ du -s 14929 Размер структуры каталога /var составляет 14929 блоков. file Формат: file имя_файла Благодаря этой команде интерпретатор shell определяет тип файла. $ file core core: ELF 32–bit LSB core file of 'awk' (signal 6), Intel 80386, version 1 $ file data.f data.f: ASCII text $ file month_end.sh month_end.sh: Bourne shell script text fuser Формат: fuser параметры файл Параметры: –k Уничтожает все процессы для файла или файловой системы -u Отображает все процессы для файла или файловой системы Команда fuser применяется для отображения процессов, выполняющихся в файловой системе или для файлов, к которым осуществляется доступ. В некоторых системах возможен выбор при использовании параметров -u и – т. Совместно с командой fuser возможно применение конструкции if.
Популярные книги за неделю
wait_for_cache