Come grep output ps con le intestazioni


26

Come posso grep l'output PS con le intestazioni in posizione?

Questi due processi compongono un'app in esecuzione sul mio server ....

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

non 6-22:01:17vuol dire che è in corso da 6 giorni? Sto cercando di determinare la durata del processo in corso ...

La seconda colonna è l'id del processo? Quindi se lo faccio kill 32017ucciderà il secondo processo?

Risposte:


37
ps -ef | egrep "GMC|PID"

Sostituire "GMC" e gli psinterruttori secondo necessità.

Esempio di output:

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
Sarebbe bene aggiungere alcune informazioni sul "perché" funziona.
Elijah Lynn,

2
No, questo è un esercizio per l'utente.
Hyppy,

@ElijahLynn Corrisponde al testo nell'intestazione - in questo caso, PID. Ma potresti sostituirlo con UID, PTIME o qualsiasi altra cosa nell'intestazione ...
Ben Creasy,

5
ps -eSeleziona quindi tutti i processi ed ps -fè un elenco in formato completo che mostra le intestazioni di colonna. Quindi eseguiamo il pipe delle intestazioni di colonna e l'output su egrep, che è grep esteso e consente al pipe |di avere un significato speciale, che è OR (questo OR quello). Quindi finisci per abbinare il PID nelle intestazioni di colonna più le linee di output che contano.
Elijah Lynn,

Ho dovuto usare le virgolette semplici nel comando egrep / grep -E in Ubuntu 16.04, ad esempio: ps -ef | grep -E 'GMC|PID'
Vlax

13

Grazie a geekosaur, vorrei usare questo comando per le tue esigenze, piuttosto che un comando separato:

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

Il trucco è usare il ";" supportato dalla shell per concatenare il comando.


questo è più pulito e più robusto della risposta accettata. Non afferma che l'intestazione abbia PID al suo interno e non aggiunge complessità alla stringa grep.
7yl4r,

2
oh aspetta ... hai ps -efripetuto. ancora meglio èps -ef | { head -1 ; grep "your-pattern" ; }
7yl4r

@ 7yl4r non ha mai usato quell'abilità shell. Ho provato il tuo comando migliorato, funziona perfettamente! Ho imparato, :)
Vic Lau

3
Trovate spiegazioni su questa tecnica, chiamata 'Grouping Commands', per curiosità altrui, vedi: gnu.org/software/bash/manual/html_node/Command-Grouping.html
Vic Lau

@ 7yl4r ottima tecnica! Stavo cercando di non ripetere il comando. Il comando può anche essere raggruppati in filodiffusione: ps -ef | { head -1; grep "pattern" | head -5; }. Utile se lo schema grep-ed ha molti risultati!
dipendente dal

6

La seconda colonna è l'id del processo; Il quarto è quando è stato creato il processo (di solito è il momento in cui è stato avviato il programma, ma non sempre; considera execve()e amici); Il sesto è il tempo impiegato dalla CPU. Quindi è in esecuzione da 8 giorni e ha impiegato quasi 7 giorni di tempo CPU, che considererei preoccupante.

Ottenere l'intestazione nella stessa invocazione è nella migliore delle ipotesi complicato; Vorrei solo fare un separato ps | head -1. Potresti prendere in considerazione l'utilizzo psdei metodi di selezione propri o qualcosa del genere pgrepinvece di grep, che non è progettato per passare attraverso le intestazioni.


Qual è il 83?
Webnet,

Priorità del processo corrente, che si basa sull'utilizzo passato di CPU e I / O e sul nicevalore assegnato dall'utente o dal sistema . I numeri più piccoli hanno la priorità più alta. In questo caso, ha la greppriorità 0 perché è stato bloccato sulla lettura del disco e ha ceduto per scrivere il suo output, ed PNetTNetServer.binè un numero elevato perché utilizza costantemente il suo intervallo di tempo senza bloccare. (La pianificazione è complessa e i dettagli dipenderanno dall'esatto pianificatore utilizzato).
Geekosaur,

5

La soluzione egrep è semplice e utile, ma ovviamente dipendi dall'intestazione che contiene sempre "PID" (un presupposto più che ragionevole) e che la stessa stringa non si trova altrove. Immagino che questo sia sufficiente per le tue esigenze, ma nel caso qualcuno voglia un'alternativa c'è sed.

Sed ti lascia semplicemente dire "stampa la prima riga, quindi qualsiasi riga contenente il motivo". Per esempio:

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

Aggiungi /sed -n/d;per filtrare sed stesso:

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

/sed -n/dnon è giusto. Potrebbe esserci qualche comando esistente sed -nche si desidera stampare. Il trucco è da usare sed -n '1p; /[P]ROCESS_NAME_TO_SEARCH/p'. ;-) Nota []intorno a qualsiasi carattere nella stringa di ricerca.
anishsane,

4

alternativa più semplice: ps -ef | { head -1; grep GMC; }

sostituisci il numero con il numero di righe su cui viene visualizzata la tua intestazione.


1
Mi piace questo approccio, ma alla fine il comando richiede un altro punto e virgola. ps -ef | { head -1; grep GMC; }. Inoltre mi piace in una funzione come la seguente:function pgrep() { ps -ef | { head -1; grep $@; } }
Brett

1

potresti ottenere il pid con pgrep

pgrep PNetTNetServer

e quindi usa ps con il pid

ps u 12345

o anche unire i due in un solo comando

ps u `pgrep PNetTNetServer`

Ciò mostrerebbe solo la linea desiderata e includerebbe l'intestazione.


0

Ho scritto un piccolo programma Perl che stamperà

  • la prima riga e tutte le righe corrispondenti, se sono presenti corrispondenze, oppure
  • niente, se non ci sono corrispondenze.

Lo uso più spesso come ps | 1andre GMC, ma può anche prendere argomenti per i file (ogni file fornisce la propria riga di intestazione per le corrispondenze fatte sulle righe di quel file).



#!/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;
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.