如何找到___状态的solaris进程

时间:2010-08-03 13:10:35

标签: perl unix shell process solaris

我制作了以下脚本来搜索某些进程,显示每个进程使用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是一个低级系统调用。与readnanosleepwaitid

相同

使用此脚本,我想查找卡在pause调用中的进程。我们正试图在我们的系统中找到一个错误,我们认为它可能与此有关。

2 个答案:

答案 0 :(得分:1)

对此有两种可能的改进,具体取决于:

  1. 您是否真的需要打印pflags命令的确切输出或其中的一些信息(例如PID和标志列表?)

  2. pflags输出中的“暂停”是什么意思?在“proc”或“pflags”man-pages中没有任何地方,所有实际的标志都是大写的。根据其含义,可以在“/ proc” - Proc::processTable::Process的本机Perl实现中找到它。

    例如,Process对象包含所有标志(in a bit vector)和进程状态(我怀疑“暂停”可能是进程状态)。


  3. 如果这些问题的答案是“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输出,那么最好的优化是构造本地pflags的PID列表 - 不是一场胜利,但你仍然失去了一堆额外的分叉进程。像这样:

    #!/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);
    }
    

答案 1 :(得分:1)

在这种情况下,我不知道你认为什么是“更好的方法”,但我可以为你已有的方法提供一些技术指导:

  • grep '/[t]ransfile'

    针对grep输出的ps通常存在匹配grep进程本身的风险,这几乎是不可取的。一个简单的保护措施就是在grep模式参数中引入一个成员的字符类。

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

    grep + cut,即模式匹配后的字段提取,对于单个awk命令来说是一项简单的任务。

  • 请勿参阅$_

    更严格,更惯用的perl会省略$_的明确使用。试试next if /cannot/等。

  • open(my $wcf, ...)

    请使用词法文件句柄,否则你会被那些年龄足以记住我们无法使用它们的人所谴责。 :)