Как получить вывод ps с заголовками


26

Как я могу получить вывод PS с заголовками на месте?

Эти два процесса составляют приложение, работающее на моем сервере ....

root     17123 16727  0 16:25 pts/6    00:00:00 grep GMC
root     32017     1 83 May03 ?        6-22:01:17 /scripts/GMC/PNetT-5.1-SP1/PNetTNetServer.bin -tempdir /usr/local/GMC/PNetT-5.1-SP1/tmpData -D

это 6-22:01:17означает , что он работает уже в течение 6 дней? Я пытаюсь определить, сколько времени длился процесс ...

2-й столбец - это идентификатор процесса? Так что, если я kill 32017это сделаю, это убьет второй процесс?

Ответы:


37
ps -ef | egrep "GMC|PID"

Замените «GMC» и psпереключатели при необходимости.

Пример вывода:

root@xxxxx:~$ ps -ef | egrep "disk|PID"

UID        PID  PPID  C STIME TTY          TIME CMD
paremh1  12501 12466  0 18:31 pts/1    00:00:00 egrep disk|PID
root     14936     1  0 Apr26 ?        00:02:11 /usr/lib/udisks/udisks-daemon
root     14937 14936  0 Apr26 ?        00:00:03 udisks-daemon: not polling any devices

8
Было бы неплохо добавить информацию о том, «почему» это работает.
Элайджа Линн

2
Нет, это упражнение для пользователя.
Hyppy

@ElijahLynn Соответствует тексту в заголовке - в данном случае, PID. Но вы можете поменять его на UID, PTIME или что-то еще в заголовке ...
Бен

5
Таким образом, ps -eвыбираются все процессы, и ps -fэто полноформатный список, который показывает заголовки столбцов. Затем мы передаем заголовки столбцов и выводим их в egrep, который является расширением grep и позволяет каналу |иметь специальное значение, которое равно ИЛИ (это ИЛИ это). Таким образом, вы в конечном итоге сопоставляете PID в заголовках столбцов плюс выходные строки, которые имеют значение.
Элайджа Линн

Мне пришлось использовать простые кавычки в команде egrep / grep -E в Ubuntu 16.04, например: ps -ef | grep -E 'GMC|PID'
Vlax

13

Благодаря geekosaur, я хотел бы использовать эту команду для ваших требований, а не отдельную команду:

ps -ef | head -1; ps -ef | grep "your-pattern-goes-here"

Сложно использовать «;» поддерживается оболочкой для цепочки команды.


это чище и надежнее, чем принятый ответ. Он не утверждает, что в заголовке есть PID, и не добавляет сложности к строке grep.
7yl4r

2
о, подождите ... у вас есть ps -efповторение. еще лучшеps -ef | { head -1 ; grep "your-pattern" ; }
7yl4r

@ 7yl4r никогда не использовал эту способность оболочки. Я попробовал вашу улучшенную команду, работает отлично! Узнал, :)
Вик Лау

3
Для любопытства других людей можно найти объяснение этой техники, называемой «Группировка команд», см.
Вик Лау,

@ 7yl4r отличная техника! Я искал, как не повторить команду. Сгруппированных команда может быть даже водопроводная: ps -ef | { head -1; grep "pattern" | head -5; }. Полезно, если шаблон grep-ed имеет много результатов!
пристрастился

6

Второй столбец - это идентификатор процесса; 4-й - это когда процесс был создан (обычно это время запуска вашей программы, но не всегда; подумайте execve()и друзья); 6-е количество процессорного времени. Так что он работал в течение 8 дней и использовал почти 7 дней процессорного времени, что я бы посчитал тревожным.

Получить заголовок в одном вызове в лучшем случае сложно; Я бы просто сделал отдельное ps | head -1. Вы можете рассмотреть возможность использования psсобственных методов выбора или чего-то подобного pgrepвместо grep, которые на самом деле не предназначены для прохождения заголовков.


Что 83?
Вебнет

Приоритет текущего процесса, основанный на его прошлом использовании процессора и ввода-вывода и назначенном пользователем или системой niceзначении. Меньшие числа имеют более высокий приоритет. В этом случае grepэто приоритет 0, потому что он был заблокирован при чтении с диска и выдан для записи своих выходных данных, и PNetTNetServer.binявляется большим числом, потому что он последовательно использует свой временной интервал без блокировки. (Планирование является сложным, и детали будут зависеть от того,
какой

5

Решение egrep простое и полезное, но, конечно, вы зависите от заголовка, всегда содержащего «PID» (хотя это более чем разумное предположение) и той же строки, которая не встречается в других местах. Я предполагаю, что этого достаточно для ваших нужд, но в случае, если кто-то хочет альтернативы, есть sed.

Sed позволяет вам просто сказать «напечатать первую строку, затем любую строку, содержащую шаблон». Например:

ps auxwww | sed -n '1p; /PROCESS_NAME_TO_SEARCH/p;'

Добавить /sed -n/d;в фильтр сам по себе:

ps auxwww | sed -n '1p; /sed -n/d; /PROCESS_NAME_TO_SEARCH/p;'

/sed -n/dэто не так. Возможно, есть sed -nкакая-то существующая команда , которую вы хотите напечатать. Хитрость заключается в использовании sed -n '1p; /[P]ROCESS_NAME_TO_SEARCH/p'. ;-) Обратите внимание []на любой символ в строке поиска.
Anishsane

4

более простая альтернатива: ps -ef | { head -1; grep GMC; }

замените число на количество строк, на которых отображается ваш заголовок.


1
Мне нравится такой подход, но в конце команды нужна еще одна точка с запятой. ps -ef | { head -1; grep GMC; }, Также мне нравится эта функция, подобная следующей:function pgrep() { ps -ef | { head -1; grep $@; } }
Бретт

1

вы можете получить pid с pgrep

pgrep PNetTNetServer

а затем использовать PS с PID

ps u 12345

или даже объединить два в одну команду

ps u `pgrep PNetTNetServer`

Это покажет только строку, которую вы хотите, и включит заголовок.


0

Я написал небольшую программу на Perl, которая будет печатать

  • первая строка и все строки совпадают, если есть совпадения, или
  • ничего, если нет совпадений.

Я чаще всего использую его как ps | 1andre GMC, но он также может принимать аргументы файла (каждый файл имеет свою собственную строку заголовка для совпадений, сделанных в строках из этого файла).



#!/usr/bin/perl

#
# 1andre <regexp> [<file> ...]
#
#   1 -           first ({1}st)
# and -                  {and}
#  re - (lines matching) {re}gexp
#
# If no <files> are given (or "-" is given as a <file>) stdin is
# used.
#
# If any lines from each <file> match the <regexp>, print the
# first line from that <file> and all the matching lines from
# that <file>.
#

use strict;
use warnings;

if(scalar @ARGV < 1) {
  printf STDERR "usage: %s <regexp> [<file> ...]\n", $0;
  exit 1;
}

my $re = shift;
my $header;

while(<>) {
  if($. == 1) {
    $header = $_;
  } elsif(m/$re/) {
    if(defined $header) {
      print $header;
      undef $header;
    }
    print;
  }
} continue {
  # close resets $. when we get to the end of each file that <> is processing
  close ARGV if eof;
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.