LINUX.ORG.RU

послать фоновому процессу нажатие клавиши q


0

0

Уважаемые! Подскажите, плиз, как можно послать фоновому процессу нажатие клавиши? Для корректного завершения программы надо ей посылать q (quit), просто убивать не совсем хорошо, она буффер из памяти не дописывает в файл.

Подробнее: Имеется скрипт save-grep: #!/bin/bash filename="/`date +%y%m%d-%H%M%S`.txt" echo $filename > /lock echo "Write trace file $filename" echo "Press q to stop" /mnt/dom/dect/g1st -d | grep -e 0x3 -e 'channel number' -e \(Orig\) -e ALERTING \ -e SETUP -e RELEASE -e 'I frame' -e CONNECT -e DATE -e \(Dest\) -e PROCEEDING \ -e '[0-9][0-9]\.[0-9][0-9]\.[0-9][0-9] [0-9][0-9]:[0-9][0-9]' >> $filename

Этот скрипт я запускаю из консоли в фон: /mnt/dom/dect/save-grep & Далее командой echo $! > /save-grep.pid записываю номер ее процесса в файл. Сессия по ssh с этим компьютером на этом завершается. По истечении суток в новой сессии надо корректно завершить этот процесс посылкой ему нажатия клавиши q. Как это можно сделать ?

А если не извращаться с клавишами и фоновыми процессами, а написать правильно - перехватчик сигналов, который все правильно разруливает и прибивать программу обычным способом?

anonymous
()

Программу, запускаемую скриптом, я изменить не могу, нет на нее ничего, кроме бинарника. Да и не программер я, так, погулять вышел :).

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

Попробуй запустить свою g1st через конвейер: вместо
/mnt/dom/dect/g1st ...

нечто типа

(path to binary)/qfake|mnt/dom/dect/g1st ...

где qfake при приеме какого - нибудь сигнала (SIGHUP,
SIGUSR1 или SIGUSR1) будет посылать на дескриптор 1 строку "q\n"
и закругляться.


Die-Hard ★★★★★
()

Т.е. qfake - внешний обработчик сигналов. Идею понял, спасибо.
Жаль, реализовать пока не смогу - знаний маловато :). Только шелл более-менее и знаю.

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

alexey_p (*) (2003-09-19 18:35:12.551224):

> Жаль, реализовать пока не смогу - знаний маловато :)

Заглядывай сюда - на днях напишу. Сегодня - нет. Или мыло давай, пришлю код в районе понедельника.

Или - люди, на 20 мин. работы с отладкой - помогите!

Die-Hard ★★★★★
()

> Заглядывай сюда - на днях напишу. Сегодня - нет. Или мыло давай, пришлю код в районе понедельника
Обязательно буду заглядывать :).
Мейл - nick<СОБАКЕВИЧ>pues.podolsk.ru
Спасибо, Die-Hard, буду ждать.

alexey_p
() автор топика

Может я чего не понял, но по-моему исходная постановка задачи некорректна.

Фоновые (background) процессы никогда не получают ввод со своего терминала, более того - попытка что-нибудь с него считать приведет либо к получению SIGTTIN либо EIO (для orphaned). Т.е. процесс ожидающий ввода не может нормально функционировать в фоновом режиме.

Murr ★★
()

Сорри, я чайник. Сейчас перепроверил - действительно процесс Stopped (tty output). Теперь дошло, что его останавливают именно за input, а не за output - т.е. загнать в фон и отключить терминал действительно не получится.
Жаль - придется по-прежнему из под винды постоянно держать открытым терминал putty на эту машину и просто посылать этому окну nncron-ом нажатие q. А так хотелось убрать это на машину с линуксом и поручить крону - облом-с.
Обидно, что в винде это удалось достаточно несложно реализовать и оно работает. В линуксе без навыков программирования сделать то же самое - похоже, фигушки. Да и с ними в данном случае, видимо, вряд ли возможно. Машина, на которой я это запускаю, не совсем обычна. Это контроллер системы радиодоступа DECT, сделанный под линуксом, без винта, с флэш-диском 40 Мб. Убрано все, что можно, крона тоже нет. Имеющиеся программы без исходников - одни бинари, и их доработки ждать не приходится.
Я смог сделать запись нормального лога работы этого контроллера вышеописанным способом и еще кое-что здорово нужное для нормальной эксплуатации. Вот только если связь по локальной сети с этим компьютером прерывается, процесс остается и работает еще часа два, а в новом терминале после восстановления связи я уже пишу параллельно еще один лог с теми же записями - в общем, бардак. Да и при проведении обслуживания виндовой машины - дефрагментация диска - лог не пишется, я на ней все останавливаю на это время.
Если бы вышеописанное получилось, оно не зависело бы от связи по локалке и перезапускалось кроном с линуксовой машины. Жаль, не выйдет.

alexey_p
() автор топика

Есть программа screen, она позволяет запускать сеансы процессов на псевдотерминалках, и делать attach/detach.
По-моему это то, что тебе нужно.

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

Murr (*) (2003-09-19 23:36:56.691422):

> Фоновые (background) процессы никогда не получают ввод со своего терминала,

Почти верно. Надо только добавать "контрольного" (или как он по-русски?) терминала.

> более того - попытка что-нибудь с него считать приведет либо к получению SIGTTIN ...

Верно.

> Т.е. процесс ожидающий ввода не может нормально функционировать в фоновом режиме.

Неверно. Не может нормально функционировать в фоновом режиме процесс, ожидающий ввода со своего терминала.

Короче, в след. мессаге пример той программы, про которую я писАл. Все прекрасно работает, я проверил.

2alexey_p (*) (2003-09-20 01:39:41.831677):

Выстриги следующую мессагу в файл qfake.c, скомпилируй его gcc -o qfake qfake.c

положи получившийся бинарный файл qfake куда-нибудь в доступное место, и измени скрипт так:

(path to binary)/qfake /save-grep.pid |mnt/dom/dect/g1st ...

Программа qfake запишет свой PID в файл /save-grep.pid

Чтобы остановить бегающий в фоне скрипт, достаточно послать на этот PID сигнал SIGHUP, например, из консоли:

kill -SIGHUP `cat save-grep.pid`

Die-Hard ★★★★★
()
Ответ на: комментарий от alexey_p

#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

/*
The program is waiting for a signal THESIGNAL, see below.
Then it outputs the line "q" to the standart output and
exits with exit code 0. On error, the exit code is >0.

If there is a command line argument, the program writes it's PID
to the file with this name.
*/

#define THESIGNAL SIGHUP

/*We will use the pipe to communicate between a handler and the main function:*/
int thepipe[2];

/*The handler:*/
void theHandler(int i)
/* Sometimes, this paranoya may occurs:*/
/*int theHandler(int i)*/
{
   /*Restoring the handler - not neseccary for this case, may be removed:*/
   /*signal(THESIGNAL,&theHandler);*/

   /*Tell to the main program that the signal is here:*/
   write(thepipe[1],"\n",1);/*We assumehere that the pipe is opened by the main.*/
}


int main (int argc, char *argv[])
{
/*buffer for reading from the pipe:*/
char buf[2];

   /*Open the pipe to communicate with the handler:*/
   if(pipe(thepipe))
     return 1;/*Can't create the pipe*/

   /*Set up the handler:*/
   if( signal(THESIGNAL,&theHandler)==SIG_ERR )
     return 2;/*Can't set up the handler*/

   if(argc>1){/*Use the first cmdline argument as a file name to write PID to*/
       FILE *f=fopen(argv[1],"w");
       if(f!=NULL){/*Ok, the file is opened*/
          fprintf(f,"%d\n",getpid());/*What is a pid_t? Guess, int is enough*/
          /*Close the file - it's ready:*/
          fclose(f);
       }/*if(f!=NULL)*/
   }/*if(argc>1)*/

   /*Blocking read - the program will wait here until the handler writes something:*/
   if(read(thepipe[0],buf,1)<0)
     return 3;/*Can't read from the pipe*/

   /*Now write "q" to stdout*/
   if(write(1,"q\n",2)<0)
     return 4;/*Can't write to stdout*/

   /*close the pipe:*/
   close(thepipe[0]);
   close(thepipe[1]);

   /*That's all.*/
   return 0;
}

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