Rating@Mail.ru
IPB
Etersoft - from Windows to Linux
Etersoft
решения для перехода
с Windows на Linux
Дружественные сайты: alv.me и Rus-Linux.net

Здравствуйте, гость ( Вход | Регистрация ) Поиск · 

> 

Темы от студентов с запросами готовых решений по заданиям закрываются не глядя.

 
Reply to this topic Start new topic
> пернаправление ввода
v4567
bookmark
gyfbbdvkffmrljmmmwd
Jul 29 2017, в 14:27
Сообщение #1


Интересующийся новичок
Иконка группы

Сообщений: 95

Вставить имя   :   Цитата

Группа: Участники

Автор темы
Есть скрипт на BASH, в котором я перехватываю сигналы:
Код
# Перехватываем сигналы.
# Завершение работы, сигнал "TERM".
trap 'vozvrisxzn ; exit 0' SIGTERM
# Завершение работы, сигнал посланный комбинацией клавиш Ctrl+c.
trap 'vozvrisxzn ; exit 0' SIGINT
# Отправка в фон - нажатие Ctrl+z.
trap 'vozvrisxzn' SIGTSTP
# Возврат из фона - набор в консоли bg или fg.
trap 'izfona' SIGCONT
# Изменение размеров терминала во время работы программы.
trap 'izmrazmterm' SIGWINCH


Этот код стоит в начале скрипта. Далее после некоторого выполнения скрипта (он выводит некоторую информацию в терминал) он останавливается и ждёт нажатия клавиш командой read. Если вместо read сделать бесконечный пустой цикл, то сигналы обрабатываются сразу. Например после изменения размеров графического эмулятора терминала, выведенная информация отлично подстраивается под изменившиеся размеры терминала.
Когда же мы ждём нажатия клавиш командой read, то после изменения размеров терминала обработка этого сигнала происходит только тогда когда мы нажмём какую нибудь клавишу, то есть только тогда когда отработает команда read. Получается, что обработка сигналов происходит только после окончания выполнения команды во время которой пришёл сигнал.
Поставить маленькое время ожидания read (например -t 0.5 секунд) я не могу, мне же надо что бы сигналы обрабатывались сразу или хотя бы с маленькой задержкой, но не после тога как я нажму на клавишу.
Вариант вижу только один (да и то я не уверен что это можно сделать), read сделать в отдельной функции например fynk() и эту функцию запускать в фоне. Получится так что запуститься дополнительный экземпляр bash с этой функцией, его pid я могу узнать, получаем вот такой код:
Код
fynk &
PIDFYNK=$!


Теперь вопрос и трудность вот в чём, можно ли как то перенаправить ввод с клавиатуры то есть перенаправить стандартный входной поток (дескриптор файла 0) в этот процесс, функцию fynk и команду в этой функции read? Если можно то как это сделать?

Получается так что у меня на терминал выводит один процесс, а клавиатура должна перенаправляться в процесс работающий в фоне.

Думаю если так сделать можно, то и сигналы будут обрабатываться быстро, так как у меня в процессе запущенном непосредственно в терминале не будет команды read.

За помощь буду заранее благодарен!
Go to the top of the page
 
+Quote Post
/dev/random
bookmark
gyfbbdvkffmrljmmmwd
Jul 30 2017, в 00:41
Сообщение #2



Иконка группы

Сообщений: 4364

Вставить имя   :   Цитата

ОС: Gentoo
Город: Волгоград

Группа: Админы

1) У меня и с read всё прекрасно работает:
.
$ ( trap 'echo hello' SIGWINCH; read )
(меняю размер терминала)
hello
hello
hello
hello
hello
hello


2) Если вы запустите read в фоне, у вас будут проблемы с получением данных из него. Изменение переменной в одном сабшелле не вызывает её изменения в другом. Вам придётся передавать данные через пайпы, т.е. всё через тот же read.

3) Ну и всё-таки отвечу на ваш вопрос, хоть ответ на него и не решит вашу проблему. Чтобы разрешить фоновому процессу читать из stdin основного, нужно переадресовать ввод явным образом: cmd <&0 &
Go to the top of the page
 
+Quote Post
v4567
bookmark
gyfbbdvkffmrljmmmwd
Aug 2 2017, в 19:17
Сообщение #3


Интересующийся новичок
Иконка группы

Сообщений: 95

Вставить имя   :   Цитата

Группа: Участники

Автор темы
Если использовать просто read то работает.

Но у меня вот такая конструкция:

Код
while [ true ]
  do

    KEY=""
    zaderjka=""

    for (( i=0 ; i<10 ; i++ ))
     do
       eval $( (IFS="" read -r -s -n 1 $zaderjka key ; printf 'code %d' "'$key") 2>&1 | awk 'NR==1||NR==4 {print $1 "=" $2}' )
       if [ "$code" != "0" ] || [ "$code" = "0" -a "$zaderjka" = "" ]
        then
            KEY=$KEY$code
       fi
       zaderjka="-t 0.01"
    done
done


Вот с такой конструкцией всё останавливается и ждёт нажатия клавиши.

На другом форуме подсказали вот такую конструкцию:

Код
while [ true ]
  do

    KEY=""
    zaderjka=""

    for (( i=0 ; i<10 ; i++))
     do
       code=""
       IFS="" read -r -s -n 1 $zaderjka key && printf -v code '%d' "'$key"
       [ -n "$code" ] && KEY=$KEY$code
       zaderjka="-t 0.01"
    done
done


При такой конструкции всё нормально, почему при первой останавливалось я так и не понял.


Спасибо за:

Код
cmd <&0 &


Проверил, работает.
Go to the top of the page
 
+Quote Post
Bizdelnick
bookmark
gyfbbdvkffmrljmmmwd
Aug 2 2017, в 21:06
Сообщение #4


grammatikführer
Иконка группы

Сообщений: 12933

Вставить имя   :   Цитата

ОС: Debian GNU/Linux
Город: Санкт-Петербург

Группа: Модераторы разделов

Цитата(v4567 @ 2nd August 2017 - в 19:17) *
почему при первой останавливалось я так и не понял.

Ждало завершения сабшелла, который ждал завершения другого сабшелла.


--------------------
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
команда
новичок
нюанс
приемлемо
проблема
пробовать
трафик
Go to the top of the page
 
+Quote Post
/dev/random
bookmark
gyfbbdvkffmrljmmmwd
Aug 2 2017, в 22:04
Сообщение #5



Иконка группы

Сообщений: 4364

Вставить имя   :   Цитата

ОС: Gentoo
Город: Волгоград

Группа: Админы


i
Уведомление от модератора /dev/random
Второй вопрос отрезан в отдельную тему: Просмотр чужого терминала
Go to the top of the page
 
+Quote Post
v4567
bookmark
gyfbbdvkffmrljmmmwd
Aug 3 2017, в 12:08
Сообщение #6


Интересующийся новичок
Иконка группы

Сообщений: 95

Вставить имя   :   Цитата

Группа: Участники

Автор темы
Цитата
Ждало завершения сабшелла, который ждал завершения другого сабшелла.


Сабшеллы - это $() и eval?
Go to the top of the page
 
+Quote Post
Bizdelnick
bookmark
gyfbbdvkffmrljmmmwd
Aug 3 2017, в 12:48
Сообщение #7


grammatikführer
Иконка группы

Сообщений: 12933

Вставить имя   :   Цитата

ОС: Debian GNU/Linux
Город: Санкт-Петербург

Группа: Модераторы разделов

$() и ()


--------------------
Пишите правильно:
в консоли
вкупе (с чем-либо)
в общем
вообще
в течение (часа)
команда
новичок
нюанс
приемлемо
проблема
пробовать
трафик
Go to the top of the page
 
+Quote Post

 Reply to this topic Start new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



RSS Текстовая версия Сейчас: 22nd November 2017 - в 17:49




Rating@Mail.ru