Wie grep ps Ausgabe mit Headern

26

Wie kann ich die PS-Ausgabe mit den vorhandenen Headern überprüfen?

Diese beiden Prozesse bilden eine App, die auf meinem Server ausgeführt wird.

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

heißt das 6-22:01:17, dass es seit 6 Tagen läuft? Ich versuche herauszufinden, wie lange der Prozess schon läuft ...

Ist die 2. Spalte die Prozess-ID? Also, wenn ich es tue kill 32017, wird der 2. Prozess abgebrochen?

Webnet
quelle

Antworten:

37
ps -ef | egrep "GMC|PID"

Tauschen Sie den "GMC" und die psSchalter nach Bedarf aus.

Beispielausgabe:

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
Hyppy
quelle
8
Wäre gut, wenn du ein paar Informationen darüber hinzufügst, warum das funktioniert.
Elijah Lynn
2
Nein, das ist eine Übung für den Benutzer.
Hyppy
@ElijahLynn Entspricht dem Text in der Kopfzeile - in diesem Fall der PID. Aber Sie könnten es gegen UID, PTIME oder irgendetwas anderes im Header austauschen ...
Ben Creasy
5
So ps -ewählt alle Prozesse und ps -fist Vollformat - Liste , die zeigt , die Spaltenüberschriften. Dann leiten wir die Spaltenüberschriften weiter und geben sie an egrep aus. |Dies ist ein erweitertes grep, das der Pipe eine besondere Bedeutung gibt, nämlich ODER (dieses ODER das). So erhalten Sie eine Übereinstimmung mit der PID in den Spaltenüberschriften und den relevanten Ausgangsleitungen.
Elijah Lynn
Ich musste einfache Anführungszeichen im Befehl egrep / grep -E in Ubuntu 16.04 verwenden, zB: ps -ef | grep -E 'GMC|PID'
Vlax
13

Dank Geekosaurier möchte ich diesen Befehl für Ihre Anforderungen anstelle eines getrennten Befehls verwenden:

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

Das Schwierige ist, das ";" von der Shell unterstützt, um den Befehl zu verketten.

Vic Lau
quelle
Dies ist sauberer und robuster als die akzeptierte Antwort. Es wird nicht behauptet, dass der Header eine PID enthält, und die grep-Zeichenfolge wird nicht komplexer.
7yl4r
2
oh warte ... du hast das ps -efwiederholt. Noch besser istps -ef | { head -1 ; grep "your-pattern" ; }
7yl4r
@ 7yl4r hat diese Shell-Fähigkeit nie benutzt. Ich habe dein verbessertes Kommando ausprobiert, funktioniert einwandfrei! Habe gelernt, :)
Vic Lau
3
Eine Erklärung zu dieser Technik, die als "Gruppierungsbefehle" bezeichnet wird, finden Sie unter: gnu.org/software/bash/manual/html_node/Command-Grouping.html
Vic Lau
@ 7yl4r tolle Technik! Ich habe versucht, den Befehl nicht zu wiederholen. Der gruppierte Befehl kann sogar sein , verrohrt: ps -ef | { head -1; grep "pattern" | head -5; }. Nützlich, wenn das Muster grep-ed viele Ergebnisse hat!
süchtig
6

Die zweite Spalte ist die Prozess-ID. Der vierte ist der Zeitpunkt, an dem der Prozess erstellt wurde (dies ist normalerweise der Zeitpunkt, an dem Ihr Programm gestartet wurde, aber nicht immer; berücksichtigen Sie execve()und Freunde). 6. ist die Menge an CPU-Zeit, die verbraucht wird. Es läuft also seit 8 Tagen und verbraucht fast 7 Tage CPU-Zeit, was ich als besorgniserregend empfinde.

Es ist bestenfalls schwierig, den Header im selben Aufruf zu erhalten. Ich würde nur eine separate machen ps | head -1. Sie könnten die Verwendung pseigener Auswahlmethoden in Betracht ziehen oder so etwas wie pgrepanstelle von grep, das eigentlich nicht für die Weitergabe von Kopfzeilen ausgelegt ist.

Geekosaurier
quelle
Was ist das 83?
Webnet
Aktuelle Prozesspriorität, die auf der vorherigen CPU- und E / A-Auslastung und dem vom Benutzer oder System zugewiesenen niceWert basiert . Kleinere Nummern haben höhere Priorität. In diesem Fall grepist die Priorität 0, da sie beim Lesen und Schreiben auf der Festplatte blockiert wurde, und sie PNetTNetServer.binist eine große Zahl, weil sie ihre Zeitscheibe konsistent verwendet, ohne sie zu blockieren. (Die Planung ist komplex und die Details hängen vom genauen verwendeten
Planer ab
5

Die egrep-Lösung ist einfach und nützlich, aber Sie sind natürlich darauf angewiesen, dass der Header immer 'PID' enthält (eine mehr als vernünftige Annahme) und dass dieselbe Zeichenfolge nicht an anderer Stelle vorkommt. Ich vermute, das ist genug für Ihre Bedürfnisse, aber falls jemand eine Alternative will, gibt es sed.

Mit Sed können Sie einfach sagen: "Drucken Sie die erste Zeile, dann jede Zeile, die das Muster enthält". Beispielsweise:

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

Hinzufügen /sed -n/d;zum Filter sed selbst aus:

ps auxwww | sed -n '1p; /sed -n/d; /PROCESS_NAME_TO_SEARCH/p;'
Eduardo Ivanec
quelle
/sed -n/dstimmt nicht. Möglicherweise gibt es einen vorhandenen Befehl sed -n, den Sie drucken möchten. Trick ist zu gebrauchen sed -n '1p; /[P]ROCESS_NAME_TO_SEARCH/p'. ;-) Notiere []um ein beliebiges Zeichen im Suchstring.
Anishsane
4

einfachere Alternative: ps -ef | { head -1; grep GMC; }

Ersetzen Sie die Zahl durch die Anzahl der Zeilen, in denen Ihre Überschrift angezeigt wird.

AllBlackt
quelle
1
Ich mag diesen Ansatz, aber der Befehl benötigt am Ende ein weiteres Semikolon. ps -ef | { head -1; grep GMC; }. Ich mag es auch in einer Funktion wie der folgenden:function pgrep() { ps -ef | { head -1; grep $@; } }
Brett
1

Du könntest die PID mit pgrep bekommen

pgrep PNetTNetServer

und dann benutze ps mit der pid

ps u 12345

Oder kombinieren Sie die beiden zu einem Befehl

ps u `pgrep PNetTNetServer`

Dies würde nur die gewünschte Zeile anzeigen und die Überschrift enthalten.

James
quelle
0

Ich habe ein kleines Perl-Programm geschrieben, das gedruckt wird

  • die erste Zeile und alle übereinstimmenden Zeilen, falls Übereinstimmungen vorliegen, oder
  • nichts, wenn es keine Übereinstimmungen gibt.

Ich verwende es meistens so ps | 1andre GMC, aber es kann auch Datei-Argumente annehmen (jede Datei bietet eine eigene Kopfzeile für Übereinstimmungen, die mit Zeilen aus dieser Datei gemacht wurden).

#!/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;
}
Chris Johnsen
quelle