Linux и UNIX: программирование в shell. Руководство разработчика - Страница 107
Шестнадцатеричные символы создаются в том случае, когда пользователь вводит значения в свободные текстовые поля. Однако эти символы могут также являться частью выбранного текста меню. Для выполнения декодирования закодированной строки нужно выполнить следующее:
• заменить все символы & символами перевода строки;
• заменить все символы + пробелами;
• заменить все символы = пробелами;
• преобразовать все значения %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 "$=$n"
#в переменную VARS записываются значения отдельных полей, которые затем
#передаются команде eval, благодаря чему отдельные поля можно адресовать;
#при этом, если поля содержат пробелы, требуется удвоенная обратная косая черта
VARS=`printf "$=\$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. Для этого следует воспользоваться следующей строкой: