Чтение онлайн

ЖАНРЫ

Linux и UNIX: программирование в shell. Руководство разработчика
Шрифт:

Аналогичный подход можно, реализовать при работе со сценариями. Можно ввести понятие критического момента, который наступает при открытии большого количества файлов. Начиная с этого момента, нельзя прерывать выполнение сценария, поскольку это может повредить файлы. Для решения этой проблемы следует установить, команду 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 можно обрести большую степень контроля над "поведением" сценария при получении сигнала. Перехват и последующая обработка сигналов обеспечивают устойчивую работу сценариев.

26.4. Команда eval

Команда eval служит для оценки командной строки с целью завершения каких-либо подстановок интерпретатора shell с последующим их вызовом. Команда eval используется для расширения значений переменных (если в результате одного прохода расширения не происходит, выполняется второй проход). Переменные, для оценки которых требуется два прохода, иногда называют сложными переменными. Хотя, по моему мнению, переменные не могут быть сложными.

Команда eval также может применяться для отображения значений простых переменных; эти переменные не должны быть сложными.

$ NAME=Honeysuckle

$ eval echo $NAME

Honeysuckle

$ echo $NAME

Honeysuckle

Наилучшим методом для понимания работы команды eval является изучение оценки командной строки, выполняемой этой командой.

26.4.1. Выполнение команд, находящихся в строке

Вначале создадим небольшой файл, testf, содержащий некоторый текст. Затем переменной myfile будет присвоена команда cat testf с последующим отображением значения переменной. Благодаря этому можно проверить возможность отображения на экране содержимого файла testf.

$ pg testf

May Day, May Day Going Down

Присвоим переменной myfile строку "cat testf:

$ MYFILE="cat testf"

Если требуется вывести содержимое файла testf на экран, нужно выполнить команду cat testf.

$ echo $MYFILE

cat testf

Теперь применим команду eval для оценки значения переменной; при этом следует помнить, что eval выполняет два прохода при оценке переменной myfile.

$ eval $MYFILE

May Day, May Day Going Down

В результате этого успешно оценивается значение переменной и применяется команда cat к файлу testf. При первом проходе отображается фактическая строка "cat testf", при втором проходе выполняется содержимое строки, в данном случае cat testf.

Рассмотрим другой пример. Переменной cat_passwd будет присвоена строка "cat /etc/passwd | more". Команда eval выполняет оценку содержимого данной строки.

$ CAT_PASSWD=`cat /etc/passwd | more`

$ echo $CAT_PASSWD

cat /etc/passwd|more

$ eval

$CAT_PASSWD

root:HccPbzT5tbOOg:0:0:root:/root:/bin/sh

bin:*:l:l:bin:/bin:

daemon:*:2:2:daemon:/sbin:

adm:*:3:4:ada:/var/adm:

Команда eval также хорошо подходит для отображения значения последнего параметра, передаваемого сценарию. Значение последнего параметра уже отображалось, но в этом случае оно будет отображено снова.

$ pg evalit

#!/bin/sh

Поделиться с друзьями: