вторник, 19 января 2010 г.

BASH -скрипты и Ctrl+C

EasyPK всегда страдал тем, что не мог корректно завершиться при нажатии Ctrl+C — он просто прерывал процесс упаковки/распаковки текущего архива и переходил к следующему. Это раздражало, т.к. приходилось клацать Ctrl+C, пока архивы не закончатся. Я почему-то считал, что решить эту проблему будет стоить немалой крови — и я ошибался. В bash есть ловушки (traps), о которых и рассказать-то особо нечего — они просто выполняют команду при поступлении сигнала. Например, я дописал в начало скриптов такую строку:
trap "exit 3" KILL HUP INT TERM
Это значит, что при получении SIGTERM, SIGKILL, SIGINT или SIGHUP мой скрипт сразу же сделает exit 3, т.е. завершится с кодом выхода 3. Легко, понятно, эффективно.

Приятного кодинга!

Копируете статью — поставьте ссылку!

6 комментариев:

Анонимный комментирует...

KILL невозможно перехватить в процессе. man 7 signal.

Также будет полезно раскрыть тему о том, что в комбинации ctrl-c нет ничего магического: просто так по умолчанию настроен терминальный драйвер -- он генерирует SIGINT (man stty, man tefminfo).

Анонимный комментирует...

Аутентификации по openid не работает (по крайней мере -- на myopenid.com). Впрочем, это не Ваша вина, скорее всего, а движка.

Minoru комментирует...

2 Анонимный:

KILL невозможно перехватить в процессе. man 7 signal.
Не знал. Не нашёл в упомянутом мане такой информации, может, процитируете? Тем не менее, эксперимент подтверждает Ваши слова.

О stty и прочем писать не хочу, т.к. и сам-то не разбираюсь. Пусть уж лучше народ прочтёт Ваш комментарий и поинтересуется сам.

Что касается OpenID — это довольно известная проблема Blogger'а. Гугловцы почему-то не фиксят… :(

Kirikaza комментирует...

Насчёт перехвата KILL...

Вообще с сигналами можно делать одну из трёх вещей: перехватить, блокировать и игнорировать. Перехват как раз осуществляется в данном примере, блокировка откладывает сигнал "на будущее", а игнор забивает на сигнал. Но можно с сигналами вообще ничего не делать, тогда ядро выполнит действие по умолчанию.

Для каждого сигнала жёстко задано, что с ним можно делать. Для мягкого завершения процесс есть TERM, который можно блокировать, чтобы программа смогла сохранить данные. Для жёсткого завершения -- KILL, который блокировать нельзя и все данные программы теряются. При выключении GNU/Linux можно увидеть сообщения, из которых ясно, что сперва всем процессам рассылаются сигналы TERM, а затем самым упорным из них -- KILL.

По просьбам трудящихся цитата из man 7 signal: "The signals SIGKILL and SIGSTOP cannot be caught, blocked, or ignored."

P.S.: Вообще говоря, сигнал KILL в принципе не доходит до процесса -- ядро отбирает у процесса все ресурсы, в том числе и процессорное время, так что процесс уже работать не может и становится зомби.


P.P.S.: Крайне рекомендую книгу "Немет Э., Снайдер Г., Сибасс С., Хейн Т. Р. UNIX: руководство системного администратора". У самого под рукой всегда третье издание. Есть ещё вариант для Linux почти тех же авторов -- Руководство администратора Linux

Minoru комментирует...

Kirikaza, спасибо за мини-лекцию! Я, признаться, совершенно не интересовался механизмом работы сигналов, а в man 7 signal основное внимание уделил таблице, а не тексту.

За рекомендации спасибо — но я пока не настолько глубоко интересуюсь работой nix, чтобы их читать :)

NucleoFag комментирует...

Идея решения чем-то напиминает пропускание фильтром через yes для собственно ответа "y" (yes) на какие-либо вопросы)

Отправить комментарий

Примечание. Отправлять комментарии могут только участники этого блога.

 
Blogger logo Debian logo Creative Commons License FeedBurner Subscribers Counter