Как исключить родительские процессы Unix из grepped output из ps

90
7

У меня есть файл 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.

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

Кто-нибудь знает, как я могу изменить свою команду, чтобы исключить родительский процесс, имея в виду, что у меня может быть много идентификаторов процесса в моем исходном файле?

спросил(а) 2015-12-22T05:34:00+03:00 4 года, 10 месяцев назад
1
Решение
58

Трудно сделать только с 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});
}
}

ответил(а) 2015-12-22T05:55:00+03:00 4 года, 10 месяцев назад
58

Используйте эту команду:

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

ответил(а) 2015-12-22T05:47:00+03:00 4 года, 10 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема