LINUX.ORG.RU

перехвать сигнала SIGTSTP в bash скрипте

 


0

1

В bash скрипте прячу курсор и отключаю эхо командами:

# Отключаем эхо.
 stty -echo
 tput reset
 # Прячем курсор.
 tput civis

Отлавливаю сигнал SIGTSTP командой:

trap 'vfon' SIGTSTP

в функции vfon возвращаю курсор и включаю эхо командами:

 tput reset
 # Делаем видимым курсор.
 tput cnorm
 # Включаем эхо.
 stty echo

но это не работает. Подскажите как включить эхо и вернуть курсор?


И ещё вопрос, как перехватить нажатие клавиш F1 и Esc?

★★

Не знаю. У меня в konsole всё работает. Скопипастил текст скрипта, получил что-то вроде этого:

#!/bin/bash

vfon()
{
 tput reset
 # Делаем видимым курсор.
 tput cnorm
 # Включаем эхо.
 stty echo
}

stty -echo
tput reset
# Прячем курсор.
tput civis

trap 'vfon' SIGTSTP

while true
  do
   echo input any text:
   read xxx
  done

exit 0

Запускаю скрипт и вижу:

input any text:
input any text:
input any text:

теперь жму ctrl+z и вижу:

123
input any text:
456
input any text:
789
input any text:
012
input any text:

Также проверил в настоящей текстовой консоли. Тоже всё работает.

Так что всё Ok. А если это не работает, то копать, видимо, надо где-то в кривых настройках terminfo или чего-то ещё, с ним связанного.

ОС: Debian Jessie.

aureliano15 ★★
()
Ответ на: комментарий от v4567

у меня уходит в фон и выводится буква «p» и курсор мигает на следующем символьном месте это в консоли 80x25. Если дальше нажать энтер то выводится строка
input any text:
если опять нажать энтер, то опять выводится эта же строка, между строк цифр нет просто пустые строки.
Если набрать jobs и нажать энтер, то опять выведется эта строка и всё, никаких заданий в фоне не покажет, вывести из фона командой fg то же не получается, выведется опять эта строка.
Если я запускаю свой скрипт, то у меня после отправки в фон, курсор мигает но набирая что нибудь на клавиатуре на экране ничего нет. Нажимаю Ctrl+c тогда только убиваю свой скрипт и возвращается консоль, соответственно в фоне уже ничего нет и в процессах скрипта нет.

v4567 ★★
() автор топика
Ответ на: комментарий от v4567

при этом например mc уходит в фон нормально, всё работает и возвращается из фона то же нормально.

v4567 ★★
() автор топика
Ответ на: комментарий от v4567

у меня уходит в фон и выводится буква «p»

Не совсем понял, о какой отправке в фон идёт речь. По условию задачи посылается сигнал SIGTSTP, который по умолчанию приостанавливает процесс, после чего его можно перевести в фон/вывести из фона. Но у нас этот сигнал перехватывается, поэтому скрипт при его получении не приостанавливается, а просто стирает экран и затем восстанавливает режим отображения текста и курсора.

Соответственно, встречные вопросы:

1. Что происходит, когда запускается моя версия скрипта?

2. Что происходит по ctrl+z с моей версией скрипта?

3. Что происходит, если моей версии передать сигнал SIGTSTP командой kill с другого терминала так:

kill -TSTP pid_процесса_со_скриптом

4. А если передать по номеру сигнала:

kill -20 pid_процесса_со_скриптом

5. Помимо 20-ого сигнала попробовать номера сигналов 18 и 24.

6. Выложить вывод скрипта до и после посылки сигнала между тегами [code] и [/code], чтоб строки не объединялись.

7. Какая ОС используется?

8. Если с моей версией скрипта всё нормально, то выложить свою версию.

терминал xterm

С xterm тоже попробовал, и у меня и на нём всё нормально.

а как F1 и Esc перехватить, при помощи read?

Что такое «перехватить» в данном контексте? Просто прочитать? Так же, как и любые другие символы. При нажатии на Esc вводится символ с десятичным кодом 27, обычно отображаемый на экране как 2 символа «^[». При нажатии F1 вводится Esc-последовательность, начинающаяся с Esc, за которым идут символы O и P.

Подробнее узнать, что когда выводится можно по команде infocmp. Параметр kf1 как раз обозначает клавишу F1.

aureliano15 ★★
()
Ответ на: комментарий от aureliano15

Все эксперименты для чистоты провожу в буквенно-текстовой консоли 80х25 с терминалом xterm

1. Что происходит, когда запускается моя версия скрипта?

чистый экран, слева вверху надпись:

pinput any text:
именно pinput а не input, вылазит откуда то букавка «p».

2. Что происходит по ctrl+z с моей версией скрипта?

p

и с парва от «p» мигает курсор далее приведу вывод полсе нескольких нажатий энтер и набора jobs и fg

input any text:

input any text:

input any text:

input any text:

input any text:
jobs
input any text:
fg
input any text:

3. Что происходит, если моей версии передать сигнал SIGTSTP командой kill с другого терминала так:

то же самое что и после нажатия ctrl+z

4. А если передать по номеру сигнала:

то же самое, что и раньше.

5. Помимо 20-ого сигнала попробовать номера сигналов 18 и 24.

сигнал 18 запуск скрипта

pinput any text:
передача сигнала 18
pinput any text:
нажатие энтер, несколько раз, при наборе на клавиатуре в терминал не выводится.
pinput any text:
input any text:
input any text:
input any text:
согнал 24
pinput any text:
Превышен лимит процессорного времени

и возврат командной строки

6. Выложить вывод скрипта до и после посылки сигнала между тегами [code] и [/code], чтоб строки не объединялись.

сделал выше.

7. Какая ОС используется?

старая русифицированная федора 11 версии.

8. Если с моей версией скрипта всё нормально, то выложить свою версию.

получается не всё нормально, ведь после нажатия на ctrl+z мне должна была вернуться командная строка, где я по команде jobs могу увидеть этот процесс в фоновых задачах, а командная срока не вернулась и по jobs ничего не показывает. Или я не прав?

v4567 ★★
() автор топика
Ответ на: комментарий от v4567

после нажатия на ctrl+z мне должна была вернуться командная строка, где я по команде jobs могу увидеть этот процесс в фоновых задачах, а командная срока не вернулась и по jobs ничего не показывает. Или я не прав?

Нет. Приостановка процесса и возврат в командную строку с возможностью перевести процесс в фоновый режим (bg номер_задания) или обратно на передний план (fg номер_задания) происходит при получении сигнала SIGTSTP по умолчанию (т. е. когда сигнал явно не обрабатывается и не игнорируется). В скрипте сигнал обрабатывается, обработчиком является функция vfon, заданная в команде trap. Соответственно, обработчик по умолчанию (остановка) отключается. Поэтому реакция должна быть такой, как указано в этой функции. А именно: перезапуск терминала в нормальном режиме (tput reset, у меня при этом очищается экран и курсор устанавливается в левый верхний угол), включение отображения курсора (tput cnorm) и включение отображения вводимых символов (stty echo). И всё. Никаких остановок и переходов в командную строку происходить не должно.

Скрипт работает правильно.

Сначала

нажатие энтер, несколько раз, при наборе на клавиатуре в терминал не выводится.

pinput any text:
input any text:
input any text:
input any text:

курсор и вводимый текст не отображаются, т. к. их отображение было отключено.

Затем, при получении сигнала SIGTSTP:

p

и с парва от «p» мигает курсор далее приведу вывод полсе нескольких нажатий энтер и набора jobs и fg

input any text:

input any text:

input any text:

input any text:

input any text:
jobs
input any text:
fg
input any text:

Как видим, вводимый текст снова начал отображаться (символы новой строки (enter), jobs, fg).

Единственно непонятно, откуда берётся «p». У меня её нет. Видимо в твоей системе она выводится при выполнении команды

tput reset
Посмотри man tput (какие последовательности она выводит) и что выводят эти последовательности (команда infocmp). У меня «tput reset» выводит строку инициализации (см. man 5 terminfo) и rs1, rs2, rs3, rf. Команда infocmp показывает, что rs1=\Ec, rs2=\E[!p\E[?3;4l\E[4l\E>, rs3 и rf у меня не определены.

Если же тебе нужно восстановить отображение курсора и вводимых символов при получении сигнала SIGTSTP, но при этом одновременно остановить задание, то функцию vfon() надо переписать следующим образом:

vfon()
{
 tput reset
 # Делаем видимым курсор.
 tput cnorm
 # Включаем эхо.
 stty echo
 trap - SIGTSTP
 kill -TSTP $$
}

Я добавил в функцию 2 доп. строки. 1-ая восстанавливает реакцию на этот сигнал по умолчанию, отменяя вызов vfon(), а вторая повторно посылает сигнал вызвавшему скрипту (в переменной $$ хранится его pid).

aureliano15 ★★
()
Ответ на: комментарий от aureliano15

Я добавил в функцию 2 доп. строки. 1-ая восстанавливает реакцию на этот сигнал по умолчанию, отменяя вызов vfon(), а вторая повторно посылает сигнал вызвавшему скрипту (в переменной $$ хранится его pid).

Понял, спасибо, попробую.

v4567 ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.