Linux и UNIX: программирование в shell. Руководство разработчика
Linux и UNIX: программирование в shell. Руководство разработчика читать книгу онлайн
Данная книга является практическим руководством по программированию интерпретатора Bourne shell -cтандартного командного интерпретатора в UNIX, полностью совместимого с интерпретатором BASH shell в Linux. Книга предназначена для начинающих и опытных программистов и содержит множество полезных примеров, советов и подсказок. С ее помощью читатель сможет быстро научиться создавать shell–сценарии для реальных задач и ситуаций, возникающих в большинстве систем UNIX и Linux.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
trap "my_exit" 1 2 3 15
LOOP=0
# временные файлы
HOLD1=/tmp/HOLD1.$$
HOLD2=/tmp/HOLD2.$$
my_exit() {
# функция my_exit
echo -e "nRecieved interrupt…"
echo "Do you wish to really exit ???"
echo " Y: Yes"
echo " N: No"
echo -n " Your choice [Y..N] >"
read ANS
case $ANS in
Y|y) exit 1;; # выход из сценария
N|n) ;; # возврат к обычной обработке
esac
}
# цикл while применяется здесь, например, для просмотра полей
echo -n "Enter your name :"
read NAME
echo -n "Enter your age :"
read AGE
Если при выполнении этого сценария происходит нажатие клавиш [Ctrl+C] в середине поля ввода (сразу после начала ввода имени), то пользователю предоставляется выбор: возвратиться к обычной обработке или выйти из сценария.
$ trap4
Enter your name :David Та
Received interrupt…
Do you really wish to exit ???
1: Yes
2: No
Your choice [1. .2] >2
Enter your age :
26.3.3. Блокировка терминала
Ниже приводится сценарий, в котором предлагается другой путь для перехвата сигналов в функционирующем сценарии. Сценарий lockit блокирует терминал пользователя с помощью командной строки. При этом командная строка помещается в непрерывный цикл while. Команда trap захватывает сигналы 2, 3 и 15. Если пользователь пытается прервать выполнение сценария, отображается сообщение о том, что действия пользователя не были успешными.
При первом обращении к сценарию запрашивается пароль. Для отмены блокировки терминала сведения поступают из устройства /dev/tty, следовательно, отсутствует запрос на разблокировку терминала; нужно просто ввести пароль и нажать клавишу ввода.
Если пользователь забыл пароль, нужно зарегистрироваться на другом терминале и устранить сценарий. Проверка длины пароля не производится, но при желании ее можно установить.
Если сценарий уничтожен с помощью другого терминала, можно вернуться на ваш терминал и разобраться с проблемами, связанными с настройками терминала: например, выяснить, почему не функционирует клавиша ввода. По командному запросу воспользуйтесь приведенной подсказкой. Это позволит устранить большую часть затруднений, связанных с терминалом.
$ stty sane
Сценарий имеет вид:
$ pg lockit
#!/bin/sh
#lockit
#перехват сигналов 2 3 и 15
trap "nice_try" 2 3 15
#устройство, на котором выполняется сценарий
TTY=`tty`
nice_try () {
# nice_try
echo "Nice try, the terminal stays locked"
}
# сохраните настройки stty, скрытие символов при вводе пароля
SAVEDSTTY=`stty -g`
stty -echo
echo -n "Enter your password to lock $TTY :"
read PASSWORD
clear
while : do
# чтение только из tty !!
read RESPONSE < $TTY
if [ "$RESPONSE"="$PASSWORD" ]; then
# пароль соответствует…разблокировка
echo "unlocking…"
break
fi
#отображение сообщения, если пользователь введет неверный пароль
#или нажмет клавишу ввода
echo "wrong password and terminal is locked.."
done
# восстановление настроек stty stty=$SAVEDSTTY
Вывод сценария lockit:
$ lockit
Enter your password to lock /dev/tty1 :
Затем экран очищается. При нажатии клавиши ввода или наборе неверного пароля сценарии выводит следующие данные:
wrong password and terminal is locked..
Nice try, the terminal stays locked
wrong password and terminal is locked..
Nice try, the terminal stays locked '
wrong password and terminal is locked..
Введите правильный пароль
unlocking… $
Теперь возвращаемся обратно, в командную строку.
26.3.4. Игнорирование сигналов
Когда пользователь регистрируется в системе, просматривается файл /etc/profile; нежелательно, чтобы пользователь прерывал этот процесс. Обычно задается перехват, или игнорирование, сигналов 1, 2, 3 и 15, но потом при просмотре сообщения motd (ежедневного сообщения) их подключают вновь (восстанавливают). Затем для игнорирования сигналов 1, 2, 3 и 15 снова устанавливается перехват.
Аналогичный подход можно, реализовать при работе со сценариями. Можно ввести понятие критического момента, который наступает при открытии большого количества файлов. Начиная с этого момента, нельзя прерывать выполнение сценария, поскольку это может повредить файлы. Для решения этой проблемы следует установить, команду trap, что позволит игнорировать некоторые сигналы. Когда завершится критический момент в функционировании сценария, примените команду trap, чтобы снова можно было захватывать сигналы.
Для игнорирования входящих сигналов (кроме сигнала 9) применяется следующая команда:
trap "" номер_сигнала:{n}
Обратите внимание, что двойные кавычки ничего не содержат. Чтобы восстановить перехват и заново захватывать сигналы, выполните команду:
trap "любые действия" номер_сигнала:{n}
Суммируем сведения о процессах игнорирования и выявления сигналов.
trap "" 1 2 3 15 # игнорирование сигналов code that does really critical stuff
trap "my_exit" 1 2 3 15 # выполните снова захват сигналов с помощью функции
# my_exit
Обратите внимание на сценарий, выполняющий критическую обработку. Цикл while аккуратно передвигает имеющийся критический момент. Для игнорирования сигналов 2, 3 и 15 применяется команда trap. После завершения цикла while, завершается еще один цикл while, но перехват уже восстановлен и прерывания разрешены.
Оба цикла while выполняются до завершения шести итераций, затем в цикле активизируется команда sleep. Благодаря этому имеется достаточно времени для того, чтобы прервать выполнение сценария.
Рассмотрим следующий сценарий:
$ pg trap_ignore
#!/bin/sh
#trap_ignore
#игнорирование сигналов
trap "" 1 2 3 15
LOOP=0
my_exit ()
# my_exit
{
echo "Received interrupt on count $LOOP"
echo "Now exiting…" exit 1
}
# критическая обработка, нельзя прерывать….
LOOP=0
while : do
LOOP=`expr $LOOP + 1`
echo "critical processing..$LOOP..you cannot interrupt me"
sleep 1
if [ "$LOOP" -eq 6 ]; then
break
fi
done
LOOP=0
#критическая обработка завершена, перехват задан снова, но разрешены прерывания
trap "my_exit" 1 2 3 15
while :
do
LOOP=`expr $LOOP + 1`
echo "Non‑critical processing..$LOOP..interrupt me now if you want"
sleep 1
if [ "$LOOP" -eq 6 ]; then
break
fi
done
Если в процессе работы этого сценария попытаться нажать клавиши [Ctrl+C] во время выполнения первого цикла "критической обработки", ничего не произойдет. Это связано с тем, что была введена команда trap для игнорирования сигналов.
После того как начинается второй цикл "некритической обработки", статус команды trap восстанавливается, в результате чего разрешаются прерывания.
$ trap_ignore
critical processing..1..you cannot interrupt me
critical processing..2..you cannot interrupt me
critical processing..3..you cannot interrupt me
critical processing..4..you cannot interrupt me
critical processing..5..you cannot interrupt me
critical processing..6..you cannot interrupt me
Non‑critical processing..1..interrupt me now if you want
Non‑critical processing..2..interrupt me now if you want
Received interrupt on count 2
Now exiting…
Благодаря применению команды trap можно обрести большую степень контроля над "поведением" сценария при получении сигнала. Перехват и последующая обработка сигналов обеспечивают устойчивую работу сценариев.