如何从ps的grepped输出中排除父Unix进程

时间:2015-12-22 02:35:00

标签: unix

我有一个pids文件,并使用ps -f来获取有关pids的信息。

这是一个例子..

ps -eaf | grep -f myfilename

myuser 14216 14215  0 10:00 ?        00:00:00 /usr/bin/ksh /home/myScript.ksh
myuser 14286 14216  0 10:00 ?        00:00:00 /usr/bin/ksh /home/myScript.ksh

其中myfilename仅包含14216。

我有一个小问题,输出给我父进程ID以及子进程。我想排除父进程ID的行。

有没有人知道如何修改我的命令来排除父进程,记住我的输入文件中可能有很多进程ID?

2 个答案:

答案 0 :(得分:1)

使用此命令:

ps -eaf | grep -f myfilename | grep -v grep | grep -f myfilename

答案 1 :(得分:1)

仅使用grep很难处理,但很容易使用awk

从以下命令调用下面的awk脚本:

ps -eaf | awk -f script.awk myfilename -

这是脚本:

# process the first file on the command line (aka myfilename)
# this is the list of pids
ARGIND == 1 {
    pids[$0] = 1
}

# second and subsequent files ("-"/stdin in the example)
ARGIND > 1 {
    # is column 2 of the ps -eaf output [i.e.] the pid in the list of desired
    # pids? -- if so, print the entire line
    if ($2 in pids)
        printf("%s\n",$0)
}

<强>更新

使用GNU awk(gawk)时,可能会忽略以下内容。对于其他[废弃]版本,请在顶部插入以下代码:

# work around old, obsolete versions
ARGIND == 0 {
    defective_awk_flag = 1
}
defective_awk_flag != 0 {
    if (FILENAME != defective_awk_file) {
        defective_awk_file = FILENAME
        ARGIND += 1
    }
}

更新#2:

以上都很好。只是为了好玩,这是另一种与perl做同样事情的方法。其中一个优点是脚本中可以包含所有内容,并且不需要管道。

通过以下方式调用脚本:

./script.pl myfilename

而且,这里有script.pl。注意:我不会写惯用的 perl。我的风格更像是人们期望在C,javascript等其他语言中看到的:

#!/usr/bin/perl

master(@ARGV);
exit(0);

# master -- master control
sub master
{
    my(@argv) = @_;
    my($xfsrc);
    my($pidfile);
    my($buf);

    # NOTE: "chomp" is a perl function that strips newlines

    # get filename with list of pids (e.g. myfilename)
    $pidfile = shift(@argv);

    open($xfsrc,"<$pidfile") ||
        die("master: unable to open '$pidfile' -- $!\n");

    # create an associative array (a 'hash" in perl parlance) of the desired
    # pid numbers
    while ($pid = <$xfsrc>) {
        chomp($pid);
        $pid_desired{$pid} = 1;
    }

    close($xfsrc);

    # run the 'ps' command and capture its output into an array
    @pslist = (`ps -eaf`);

    # process the command output, line-by-line
    foreach $buf (@pslist) {
        chomp($buf);

        # the pid number we want is in the second column
        (undef,$pid) = split(" ",$buf);

        # print the line if the pid is one of the ones we want
        print($buf,"\n")
            if ($pid_desired{$pid});
    }
}