Как найти процесс соляриса со статусом ___ - PullRequest
0 голосов
/ 03 августа 2010

Я сделал следующий скрипт, который ищет определенные процессы, отображает, использует pflags для каждого и останавливается, когда находит скрипт со словом «pause»:

!cat find_pause
#!/usr/bin/perl -W

use warnings;
use strict;

if (open(WCF,
         "ps -ef | grep '/transfile' | cut -c10-15 | xargs -n1 pflags 2>&1 |"
   )) {
    while (<WCF>) {
       next if ($_ =~ /cannot/);
       print $_;
       last if ($_ =~ /pause/);
    }
    close(WCF);
}

Это работает, но мне интересно, есть ли лучший способ сделать это.

Обновление

pause - системный вызов низкого уровня. Как read, nanosleep, waitid и т. Д.

С помощью этого скрипта я хочу найти процессы, которые застряли в вызове pause. Мы пытаемся найти ошибку в нашей системе и думаем, что это может быть связано с этим.

Ответы [ 2 ]

1 голос
/ 03 августа 2010

Я не знаю, что вы считаете «лучшим способом» в этом случае, но я могу предложить некоторые методические рекомендации для подхода, который у вас уже есть:

  • grep '/[t]ransfile'

    A grep против вывода ps часто рискует совпасть с самим процессом grep, что почти никогда не требуется.Легкой защитой от этого является простое введение класса символов одного члена в аргументе grep.

  • awk '/\/[t]ransfile/{ print $2 }'

    grep + cut, то есть извлечение поля после сопоставления с шаблоном, является простой задачей для отдельной команды awk.

  • Не относится к $_

    Более жесткий идиоматичный perl исключит явное использование $_.Попробуйте next if /cannot/ и т. П.

  • open(my $wcf, ...)

    Пожалуйста, используйте лексические дескрипторы файлов, в противном случае вас будут упрекать те, кто достаточно стар, чтобы помнить, когда мы не моглине использовать их.:)

1 голос
/ 03 августа 2010

Есть два возможных улучшения в зависимости от:

  1. Вам действительно требуется распечатать точный вывод команды pflags или некоторую информацию из нее (например, список PID и флагов?)

  2. Что означает «пауза» в выводе pflags? Это нигде в man-страницах "proc" или "pflags" и все фактические флаги в верхнем регистре. В зависимости от его значения он может быть найден в нативной реализации Perl "/ proc" - Proc :: processTable :: Process .

    Например, этот объект Process содержит все флаги ( в битовом векторе ) и состояние процесса (я подозреваю, что «пауза» может быть состоянием процесса).


Если ответы на эти вопросы « Proc :: processTable :: Process содержит достаточно информации для моих нужд», то лучшим решением будет использование этого:

#!/usr/bin/perl -W
use warnings;
use strict;

use Proc::ProcessTable;

my $t = new Proc::ProcessTable;
foreach $p ( @{$t->table} ) {
   my $flags = $p->pid; # This is an integer containing bit vector.
   # Somehow process $flags or $p->status to find "if the process is paused"
   print "$flags\n";
   last if paused($p); # No clue how to do that without more info from you
   # May be : last if $p->status =~ /paused/;
}

Однако, если нативный процесс Perl не имеет достаточной информации для вас (маловероятно, но возможно), ИЛИ, если вы по какой-то причине захотите вывести точный вывод pflags как есть, лучшая оптимизация - создать список PID для pflags изначально - не такая уж большая победа, но вы все равно потеряете кучу лишних разветвленных процессов. Примерно так:

#!/usr/bin/perl -W
use warnings;
use strict;

use Proc::ProcessTable;

my $t = new Proc::ProcessTable;
my $pids = join " ", map { $_->pid } @{$t->table};
if (open(WCF, "pflags 2>&1 $pids|")) {
    while (<WCF>) {
       next if ($_ =~ /cannot/);
       print $_;
       last if ($_ =~ /pause/);
    }
    close(WCF);
}

...