Как я могу проверить, запущен ли процесс Unix в Perl? - PullRequest
4 голосов
/ 02 октября 2010

В UNIX я проверяю, запущен ли процесс, выполнив следующую команду:

* 1003 Е.Г. *

psg dtllst pe99

Возвращает следующий вывод, если процесс запущен;

UID    PID    PPID    C    STIME    TTY    TIME CMD
pe99   1234   1       0 03:29:44    pts/8  0:01 dtllst pe99

Теперь в Perl я хочу узнать, запущен ли этот процесс или нет. Пока я делаю следующее

`my $checkProc = `psg dttlst | grep $myNode 2>&1`;`    #where $myNode is something like pe01 or pe02 or pe65 or pe99 etc...

Теперь, после этого, я делаю следующее, чтобы посмотреть, вернула ли указанная выше команда Perl то, что я ищу, чтобы увидеть, запущен ли процесс;

if ($checkProc =~ m/dtllst $myNode | $myNode/) {
    #yes, process is up
} else {
    #no, process is down
}

Однако это не работает - в частности, независимо от того, активен процесс UNIX или нет, мой код ВСЕГДА оценивает оператор if как true. Я знаю, что это неправильно. Я попытался экранировать символ "$" в регулярном выражении, чтобы убедиться, что это проблема, и я также попытался удалить переменные Perl из регулярного выражения.

Что мне здесь не хватает? Я знаю, что мое регулярное выражение где-то не так: (

Спасибо

Ответы [ 5 ]

10 голосов
/ 02 октября 2010

Вы можете использовать Proc :: ProcessTable , чтобы избежать необходимости запуска внешней команды и анализа ее вывода. Что-то вроде

use Proc::ProcessTable;
...
my $t = Proc::ProcessTable->new;
my $is_running = grep { $_->{cmndline} =~ /^dtllst $myNode/ } @{$t->table};
6 голосов
/ 02 октября 2010

Возможно, вы соответствуете процессу grep?Вы всегда можете добавить | grep -v grep, чтобы убедиться, что вы фильтруете эту строку из вывода ps.

4 голосов
/ 16 апреля 2014

Вы могли бы использовать команду kill, кажется более чистым способом;

#!/usr/bin/perl

#-- check if process 11325 is running
$exists = kill 0, 11325;
print "Process is running\n" if ( $exists );
1 голос
/ 01 апреля 2014

Мне кажется, я знаю, почему это происходило так. Ваш код всегда оценивается как true, потому что команда psg с шаблоном, который вы используете, также появится в списке процессов, которые выводит команда psg, когда эта команда вызывается из скрипта Perl. Вместо того, чтобы выполнять сопоставление в условии if, чтобы определить, запущен ли процесс или нет, вы можете захотеть сохранить количество совпадений и считать, что процесс, соответствующий вашему шаблону, выполняется, когда число совпадений превышает 1. Вот кусок кода, который я использовал:

my $match_count = 0;
my $processes = `ps x`;
while($processes =~ m/(.*?)\n/sg)
{
    my $process = $1;
    chomp($process);
    if($process =~ m/$pattern/)
    {
        #print "$process matched $pattern \n";
        $match_count++;
    }
}

if($match_count > 1)
{
    print "The process is running";
}
1 голос
/ 02 октября 2010

Добавление к ответу @ zigdon:

Допустим, ваш $myNode равен foo, ваше регулярное выражение будет /dtllst foo | foo/

Теперь выполняется поиск строки 'dtllst foo ' или ' foo' в $checkProc.

Обратите внимание, что после 'foo' в 'dtllst foo ' есть пробел. Единственное место, где можно найти эту строку, находится в последнем столбце как CMD, но завершающий пробел приведет к сбою сопоставления.

Также у вашей альтернативы ' foo' тоже есть пробел. Если единственный способ найти процесс - это поиск 'dtllst foo', эта альтернатива не нужна, так как эта альтернатива также будет соответствовать 'foo', работающему в качестве аргумента какой-либо другой команды.

И регулярное выражение для которого:

if ($checkProc =~ m/dtllst $myNode/) {
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...