Jak grepować wyjście ps za pomocą nagłówków


26

Jak mogę grepować wyjście PS z umieszczonymi nagłówkami?

Te dwa procesy tworzą aplikację działającą na moim serwerze ....

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

nie 6-22:01:17oznacza to, że został uruchomiony przez 6 dni? Próbuję ustalić, jak długo trwa proces ...

Czy druga kolumna jest identyfikatorem procesu? Więc jeśli kill 32017to zrobię, zabije drugi proces?

Odpowiedzi:


37
ps -ef | egrep "GMC|PID"

Wymień „GMC” i ps przełączniki w razie potrzeby.

Przykładowe dane wyjściowe:

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
Dobrze byłoby dodać trochę informacji o tym „dlaczego” to działa.
— Elijah Lynn

2
Nie, to ćwiczenie dla użytkownika.
— Hyppy

@ElijahLynn Dopasowuje tekst w nagłówku - w tym przypadku PID. Ale możesz zamienić go na UID, PTIME lub cokolwiek innego w nagłówku ...
— Ben Creasy

5
ps -eWybiera więc wszystkie procesy i ps -fjest listą w pełnym formacie, która pokazuje nagłówki kolumn. Następnie potokujemy nagłówki kolumn i wyprowadzamy je do egrep, który jest rozszerzonym grep i pozwala na |specjalne znaczenie potoku , którym jest OR (to OR to). W rezultacie dopasowujesz PID w nagłówkach kolumn i linie wyjściowe, które mają znaczenie.
— Elijah Lynn

Musiałem użyć prostych cudzysłowów w poleceniu egrep / grep -E w Ubuntu 16.04, np .: ps -ef | grep -E 'GMC|PID'
— Vlax

13

Dzięki geekozaurowi chciałbym użyć tego polecenia do swoich potrzeb, a nie oddzielnego polecenia:

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

Trudne jest skorzystanie z „;” obsługiwany przez powłokę w celu połączenia polecenia.


jest to czystsze i bardziej niezawodne niż zaakceptowana odpowiedź. Nie potwierdza, że ​​nagłówek zawiera PID i nie dodaje złożoności do łańcucha grep.
— 7yl4r

2
oh czekaj ... masz ps -efpowtórzenie. jeszcze lepiej jestps -ef | { head -1 ; grep "your-pattern" ; }
— 7yl4r

@ 7yl4r nigdy nie używał tej zdolności powłoki. Próbowałem twoje ulepszone polecenie, działa idealnie! Nauczyłem się, :)
— Vic Lau,

3
Znalezione wyjaśnienie na temat tej techniki, zwanej „komendami grupowania”, dla ciekawości innych, patrz: gnu.org/software/bash/manual/html_node/Command-Grouping.html
— Vic Lau

@ 7yl4r świetna technika! Szukałem, jak nie powtarzać polecenia. Zgrupowane polecenie może nawet być odprowadzone: ps -ef | { head -1; grep "pattern" | head -5; }. Przydatne, jeśli wzór grep-ed ma wiele wyników!
— uzależniony

6

Druga kolumna to identyfikator procesu; Czwarty to czas, w którym proces został utworzony (zwykle jest to czas uruchomienia programu, ale nie zawsze; rozważexecve() i przyjaciele); Szósta to ilość zajętego czasu procesora. Działa więc od 8 dni i zużywa prawie 7 dni czasu procesora, co uważam za niepokojące.

Uzyskiwanie nagłówka w tym samym wywołaniu jest w najlepszym razie trudne; Po prostu zrobiłbym osobny ps | head -1. Możesz rozważyć użycie pswłasnych metod selekcji lub czegoś podobnego pgrepzamiast grep, który tak naprawdę nie jest przeznaczony do przepuszczania nagłówków.


Co to jest 83?
— Webnet

Bieżący priorytet procesu, który jest oparty na jego przeszłym użyciu procesora i we / wy oraz nicewartości przypisanej przez użytkownika lub system . Mniejsze liczby mają wyższy priorytet. W tym przypadku grepma priorytet 0, ponieważ został zablokowany podczas odczytu dysku i dał wynik do zapisania danych wyjściowych, i PNetTNetServer.binjest dużą liczbą, ponieważ konsekwentnie wykorzystuje swój przedział czasu bez blokowania. (Planowanie jest skomplikowane, a szczegóły zależą od używanego harmonogramu.)
— geekozaur

5

Rozwiązanie egrep jest proste i użyteczne, ale oczywiście zależy od nagłówka, który zawsze zawiera „PID” (choć bardziej niż rozsądne założenie) i ten sam ciąg znaków, który nie występuje nigdzie indziej. Domyślam się, że to wystarczy dla twoich potrzeb, ale w przypadku, gdy ktoś chce alternatywy, jest sed.

Sed pozwala po prostu powiedzieć „wydrukuj pierwszą linię, a następnie dowolną linię zawierającą wzór”. Na przykład:

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

Dodaj, /sed -n/d;aby odfiltrować sed:

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

/sed -n/dnie jest dobrze. Być może istnieje istniejące polecenie sed -n, które chcesz wydrukować. Sztuką jest używać sed -n '1p; /[P]ROCESS_NAME_TO_SEARCH/p'. ;-) Uwaga []wokół dowolnego znaku w ciągu wyszukiwania.
— anishsane

4

łatwiejsza alternatywa: ps -ef | { head -1; grep GMC; }

zamień liczbę na liczbę wierszy, w których wyświetlany jest nagłówek.


1
Podoba mi się to podejście, ale polecenie wymaga na końcu innego średnika. ps -ef | { head -1; grep GMC; }. Podoba mi się również w funkcji takiej jak:function pgrep() { ps -ef | { head -1; grep $@; } }
— Brett

1

możesz dostać pid z pgrep

pgrep PNetTNetServer

a następnie użyj ps z pid

ps u 12345

lub nawet połączyć je w jedno polecenie

ps u `pgrep PNetTNetServer`

Spowoduje to wyświetlenie tylko żądanej linii i dołączenie nagłówka.


0

Napisałem mały program w Perlu, który wydrukuje

  • pierwsza linia i wszystkie linie pasujące, jeśli są jakieś dopasowania, lub
  • nic, jeśli nie ma żadnych dopasowań.

Najczęściej używam go w ten sposób ps | 1andre GMC, ale może również przyjmować argumenty pliku (każdy plik ma własną linię nagłówka dla dopasowań wykonanych w liniach z tego pliku).



#!/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;
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.