Модераторы: korob2001, ginnie
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помогите! Не работает exec и system тоже :(, После fork перестает работать exec  
:(
    Опции темы
lyl8000
Дата 4.8.2008, 09:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 4.8.2008

Репутация: нет
Всего: нет



В перле новичок, поэтому не очень понимаю, возможно простые вещи.

Итак, есть код:

Код

#!/usr/bin/perl

use strict;
require 'sys/syscall.ph';

$ENV{SHELL} = '/bin/bash';
$ENV{PATH} = '/bin:/usr/bin';

$0='radius_watch_dog';
fork() && exit;

close STDOUT; close STDERR; close STDIN;

chdir '/';

syscall(&SYS_setsid);

$SIG{'INT'} = $SIG{'QUIT'} = $SIG{'TERM'} = 'quit';
$SIG{'HUP'} = 'ignore';

sub quit        {
                        exit(0);
                }

open(LOG, ">/opt/watch_dog_log.log");

my ($t,$p);

while(1)
{
sleep(10);
$p=exec("/sbin/pidof radiusd");
print LOG "pid=$p\n";
print LOG " ::::: radius ok.\n";
if ($p eq 256)
        {
                $t=system("date");
                print LOG "$t ::::: radius not found. restart \n";
                exec("/etc/init.d/radius.sh restart");
        }
}

close LOG;



Вопрос такой. Если не делать fork и отключение от консоли то все работает нормально, как только ставлю форк и отключаюсь от консоли  вызовы exec или system перестают работать.....

Что делать? Как быть? 
PM MAIL   Вверх
sir_nuf_nuf
Дата 4.8.2008, 09:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 920
Регистрация: 6.1.2008

Репутация: 14
Всего: 31



Привет!

В чем это выражается ?
то что после fork() перестает работать exec() - это мистика =)
Скорее всего проблема в другом. Что именно происходит не так, может не видно какого-то эффекта ?

По пути, если ты хочешь писать демона - глянь на 
Daemon::Generic
удобная штука.


--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
korob2001
Дата 4.8.2008, 10:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

Репутация: 31
Всего: 61



Я так понимаю нужны зомби? Может это поможет?
Код

$SIG{CHLD} = "IGNORE";



--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
sir_nuf_nuf
Дата 4.8.2008, 10:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 920
Регистрация: 6.1.2008

Репутация: 14
Всего: 31



ээ... подождите, а что вы вообще ожидаете получить ?
Код

$p=exec("/sbin/pidof radiusd");


Вот в этом месте ваша программа кончается. exec подменяет вашу программу (perl) на pidof. 
все что написано после exec НЕ выполняется никогда (конечно если только exec не обвалится)

pidof ? я так понимаю вы хотите получить pid  процесса radiusd?

тогда вам надо делать скорее так
Код

$p=`/sbin/pidof radiusd`;  # тут обратные кавычки


а вообще узнавать пид по имени - плохая затея.
каждый процесс может узнать свой пид 
так:
Код

my $self_pid = getpid();


или так
Код

my $self_pid = $$;


пид дочернего процесса возвращается родителю при вызове fork():
Код

if (my $pid = fork()) {
    #in parent
    print("child forked $pid \n");
} else {
    #in child
    print("i'm a child $$ \n");
}




--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
lyl8000
Дата 4.8.2008, 12:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 4.8.2008

Репутация: нет
Всего: нет



другими словами я пишу что то вроде программки, которая через определенный интервал времени проверяет заупущен ли радиус.
если его pid -1 это значит что он не запущен и его надо запустить.

вроде бы все просто.... но...

написал подругому:
Код

#!/usr/bin/perl

fork && exit;

print "i am forked\n";

close STDIN;
close STDOUT;
close STDERR;

open (FILE, '>/opt/log.log');
while(1)
    {
        sleep(5); 
        $p=`pidof radiusd`;            #получаем pid
        @m=split(" ",$p);                 #процессов несколько, поэтому их в массив запихиваем

        foreach(@m)
            {
                print FILE "$_\t";         # печатаем список ПИДов в файл (для отладки)
            }
        print FILE "\n";

        print FILE $#m."\n";            # печатаем кол-во элементов массива (для отладки)

        if (($#m+1)<1)                    # если кол-во ПИДов меньше 1 то перезапускаем радиус....
            {
                $call=`/etc/init.d/radius.sh restart`;    # перезапуск радиуса
                $t=`date`;
                print FILE "$t\t :::\t radius restart.";
            }
        print FILE "$p\n";
    }

close FILE;



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

вот ..... помоему я чего то глобального не понимаю.... подскажите плиз :'(
PM MAIL   Вверх
GoDleSS
Дата 4.8.2008, 13:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 105
Регистрация: 11.2.2007
Где: Пироговский

Репутация: 2
Всего: 2



Цитата

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


Не хватает прав скорее всего.
Запущен скрипт из под пользователя такого-то, а этот пользователь в логауте.
Скрипт пытается делать вызовы внешних программ уже с другими правами.

Может и ошибаюсь, но интуиция подсказывает, что копать в указанном направлении smile
--------------------
It's a nice day to die my friend!
PM MAIL WWW ICQ   Вверх
sir_nuf_nuf
Дата 4.8.2008, 13:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 920
Регистрация: 6.1.2008

Репутация: 14
Всего: 31



выводите в лог результат выполнения `ваш скрипт`, а так же переменные $? и $^E 

вот так:
Код

$call=`/etc/init.d/radius.sh restart`;    # перезапуск радиуса
$t=`date`;
print FILE "$t: \t result: '$call' \t os err: '$^E' \t script err: '$?'\n";


логи пришлите сюда.

вы уверены, что такое происходит именно при закрытии консоли?
может сам ваш скрипт останавливается ?


--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
lyl8000
Дата 4.8.2008, 14:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 4.8.2008

Репутация: нет
Всего: нет



логи в студию!
Код


.......

7517 7516 7515 7514 7513 7502

7517 7516 7515 7514 7513 7502

7517 7516 7515 7514 7513 7502                                     <<<<<<<<<---------- тут вручную убиваю радиус

Mon Aug  4 14:45:12 MSD 2008
:        result: 'Starting authorize radiusd:
'        os err: 'Bad file descriptor'   script err: '0'


7585                                                                                  <<<<<<<< ------------ тут радиус меееееедленно перезапускается этим скриптом

7585

7585

7585

7585

7612 7611 7610 7609 7608 7585

7612 7611 7610 7609 7608 7585



это когда я в консоли еще.

а вот случай когда я вышел из консоли и зашел снова:

Код

7612 7611 7610 7609 7608 7585

7612 7611 7610 7609 7608 7585

7612 7611 7610 7609 7608 7585                                     <<<<<<---------тут вручную убиваю радиус

Mon Aug  4 14:46:07 MSD 2008
:        result: 'Starting authorize radiusd:                         <<<<<<<--- вот эту фразу кстати пишет скрипт /etc/init.d/radius.sh  но радиус не поднимается :(
'        os err: 'Bad file descriptor'   script err: '0'


Mon Aug  4 14:46:12 MSD 2008
:        result: 'Starting authorize radiusd:
'        os err: 'Bad file descriptor'   script err: '0'


Mon Aug  4 14:46:17 MSD 2008
:        result: 'Starting authorize radiusd:
'        os err: 'Bad file descriptor'   script err: '0'


Mon Aug  4 14:46:22 MSD 2008
:        result: 'Starting authorize radiusd:
'        os err: 'Bad file descriptor'   script err: '0'


Mon Aug  4 14:46:27 MSD 2008
:        result: 'Starting authorize radiusd:
'        os err: 'Bad file descriptor'   script err: '0'


Mon Aug  4 14:46:32 MSD 2008
:        result: 'Starting authorize radiusd:
'        os err: 'Bad file descriptor'   script err: '0'


Mon Aug  4 14:46:37 MSD 2008
:        result: 'Starting authorize radiusd:
'        os err: 'Bad file descriptor'   script err: '0'




во втором случае радиус так и не перезапустился.. причем фразу "Starting authorize radiusd:" пишет скрипт /etc/init.d/radius.sh . Таким образом получается что скрипт стартует, но радиус не поднимает ( а это, как я понимаю проблема уже из другой оперы..

все скрипты запускаю из под рута..
PM MAIL   Вверх
sir_nuf_nuf
Дата 4.8.2008, 14:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 920
Регистрация: 6.1.2008

Репутация: 14
Всего: 31



А) хм... по пробуй не закрывать файловые дескрипторы, а перенаправлять их в /dev/null
Код

for my $handle (*STDIN *STDOUT *STDERR) {
    open($handle, "+<", "/dev/null") || die "can't reopen to /dev/null";
}


такое ощущение, что радиус что то пытается написать в закрытый дескриптор.

Б) подмени сам скрипт radiusd =)
на что то простое:

Код

#!/usr/bin/perl 
while(1) {
  open my $fh, ">/opt/log1.log";
  print $fh $$, "\n";
  close $fh;
  sleep(3);
}


т.е. перемести бинарник и на его место положи скрипт.


--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
lyl8000
Дата 4.8.2008, 14:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 4.8.2008

Репутация: нет
Всего: нет



убрал вообще 

close STDIN; close STDOUT; close STDERR;

ничего не поменялось...

а радиус стоит на рабочем сервере, там до 200 авторизаций в секунду )) не могу его подменить... надо вощем на кошках потренироваться. smile

потренируюсь - отпишусь.

Спасибо всем за помощь!!!!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0824 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.