【问题标题】:How to find a solaris process with ___ status如何找到具有 ___ 状态的 solaris 进程
【发布时间】:2011-03-24 17:30:48
【问题描述】:

我制作了以下脚本,它搜索某些进程,显示每个进程的使用 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 调用中的进程。我们正在尝试查找系统中的错误,我们认为它可能与此有关。

【问题讨论】:

  • 您能否澄清一下pflags 输出中的“暂停”究竟是什么意思? proc pr pflags 联机帮助页中没有它,所有实际标志都是大写的。
  • 听起来“暂停”会处于“状态”?如果是这样,我用合理的逻辑更新了第一个示例

标签: perl unix shell process solaris


【解决方案1】:

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

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

  2. pflags 输出中的“暂停”是什么意思?它不在“proc”或“pflags”手册页中,所有实际标志都是大写的。根据其含义,它可能在“/proc”的本机 Perl 实现中找到 - Proc::processTable::Process

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


如果这些问题的答案是“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);
}

【讨论】:

    【解决方案2】:

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

    • grep '/[t]ransfile'

      grepps 的输出经常冒着匹配 grep 进程本身的风险,这几乎是不希望的。一个简单的保护措施就是在 grep 模式参数中引入一个成员的字符类。

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

      grep + cut,即模式匹配后的字段提取,对于单个awk 命令来说是一件容易的事。

    • 不要引用$_

      更严格、更惯用的 perl 将省略对 $_ 的显式使用。试试next if /cannot/ 之类的。

    • open(my $wcf, ...)

      请使用词法文件句柄,否则你会被那些大到记得我们什么时候不能使用它们的人责备。 :)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-24
      • 1970-01-01
      • 1970-01-01
      • 2011-06-27
      • 1970-01-01
      相关资源
      最近更新 更多