Eleganter “ps aux | grep -v grep ”

177

Wenn ich die Liste der Prozesse überprüfe und diejenigen heraushole, die für mich interessant sind, wird das grepselbst auch in die Ergebnisse einbezogen. Zum Auflisten von Terminals:

$ ps aux  | grep terminal
user  2064  0.0  0.6 181452 26460 ?        Sl   Feb13   5:41 gnome-terminal --working-directory=..
user  2979  0.0  0.0   4192   796 pts/3    S+   11:07   0:00 grep --color=auto terminal

Normalerweise benutze ich ps aux | grep something | grep -v grep, um den letzten Eintrag loszuwerden ... aber es ist nicht elegant :)

Haben Sie einen eleganteren Hack, um dieses Problem zu lösen (abgesehen davon, dass Sie den gesamten Befehl in ein separates Skript packen, was auch nicht schlecht ist)?

Jakub M.
quelle
4
Für das, was es wert ist, ist dies eine alte FAQ. Siehe Punkt 3.10 unter faqs.org/faqs/unix-faq/faq/part3
Tripleee
1
Vielen Dank für die Referenz. Das ist ihre Methode:ps ux | awk '/name/ && !/awk/ {print $2}'
Jakub M.
Was macht der grep -v grepTeil?
Jwan622
2
@ Jwan622 grep -v grepschließt grepvon grep-Ergebnissen aus. Wenn grep in Kombination mit ps verwendet wird, wird auch der grep-Prozess (mit grep-Argumenten) angezeigt, wodurch Ihre Ergebnisse unübersichtlich werden. grep -v grep ist ein üblicher Weg, um dies zu vermeiden
Eugene Platonov

Antworten:

282

Die übliche Technik ist folgende:

ps aux | egrep '[t]erminal'

Dies wird mit Zeilen übereinstimmen, die enthalten terminal, was egrep '[t]erminal'nicht! Es funktioniert auch mit vielen Unix-Varianten.

Johnsyweb
quelle
1
Dies funktioniert bei mir für eine beliebige Zeichenfolge, aber nicht für einen Benutzernamen, z ps aux | grep '[r]oot'. Weiß jemand warum?
kxsong
2
@kxsong: Wählt | grep '[t]erminal'eine Zeile aus, die das Wort 'terminal' enthält, ohne das Wort 'terminal' in die Prozessliste aufzunehmen. Was versuchst du damit zu erreichen | grep '[r]oot'und wie funktioniert es nicht? Es gibt wahrscheinlich eine bessere Lösung.
Johnsyweb
3
Korrigieren Sie mich, wenn ich falsch liege, aber dies sollte auch an jeder Position des Grep-Zeichens funktionieren: ps aux | grep "te [r] minal"
meso_2600
2
Brillanter Hack (Ich denke, ich sollte es so nennen, da die Aux / Grep-Autoren wahrscheinlich nicht an dieses Szenario gedacht haben.)
Michael Trouw
2
@JamieJag: Nun ... wie ich in meinem Beitrag sagte, grep '[t]erminal'wird mit Zeilen übereinstimmen, die enthalten terminal. Die Ausgabe von ps auxhat eine Zeile mit grep '[t]erminal'(mit eckigen Klammern), die die Zeichenfolge nicht enthält terminal(ohne dieselbe).
Johnsyweb
57

Verwenden Sie pgrep . Es ist zuverlässiger.

DarkDust
quelle
pgrepwird nicht funktionieren, wenn ich zum Beispiel nachps aux | grep 'ssh options'
Jakub M.
12
Jakub M.: Was ist mit pgrep -f?
Hillu
4
@ jakub-m Standardmäßig wird pgrepdas Muster nur mit dem Prozessnamen abgeglichen . Verwenden Sie das -fFlag , um mit dem gesamten Befehl übereinzustimmen.
Bluecollarcoder
3
pgrepGibt nur Prozess-IDs zurück.
Melab
1
ältere Versionen nahmen pgrep -fl(konnten aber keine vollständige cmdline sehen, ohne -fmit der vollständigen cmdline übereinzustimmen, Details: serverfault.com/a/619788/44183 ). Aber ja, wenn Sie neben pid, cmdline noch weitere Informationen benötigen, benötigen Sie diese ps. Kann sie kombinieren:ps -p $(pgrep -f foo)
Beni Cherniavsky-Paskin
29

Diese Antwort baut auf einer vorherigen pgrep Antwort auf . Es baut auch auf einer anderen Antwort auf, die die Verwendung von psmit kombiniert pgrep. Hier sind einige relevante Trainingsbeispiele:

$ pgrep -lf sshd
1902 sshd

$ pgrep -f sshd
1902

$ ps up $(pgrep -f sshd)
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root      1902  0.0  0.1  82560  3580 ?        Ss   Oct20   0:00 /usr/sbin/sshd -D

$ ps up $(pgrep -f sshddd)
error: list of process IDs must follow p
[stderr output truncated]

$ ps up $(pgrep -f sshddd) 2>&-
[no output]

Das Obige kann als Funktion verwendet werden :

$ psgrep() { ps up $(pgrep -f $@) 2>&-; }

$ psgrep sshd
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root      1902  0.0  0.1  82560  3580 ?        Ss   Oct20   0:00 /usr/sbin/sshd -D

Vergleichen Sie mit der Verwendung psmit grep. Die nützliche Kopfzeile wird nicht gedruckt:

$  ps aux | grep [s]shd
root      1902  0.0  0.1  82560  3580 ?        Ss   Oct20   0:00 /usr/sbin/sshd -D
Scharfsinn
quelle
Siehe github.com/blueyed/oh-my-zsh/blob/… (aber es ist spezifisch für Zsh).
blau
@blueyed, ich habe die Antwort mit der Bash-Funktionsdefinition aktualisiert.
Acumenus
Beachten Sie auch die -dOption zum Angeben eines Trennzeichens. zBps -fp$(pgrep -d , getty)
Toby Speight
1
Ich benutze dies: ps uxp `pgrep <process>` Beachten Sie, dass pdies der letzte Parameter sein muss (dh puxnicht funktioniert)
KFL
9

Sie können im Befehl ps filtern, z

ps u -C gnome-terminal

(oder durchsuchen / proc mit find etc.)

Andreas Frische
quelle
1
Beachten Sie, dass dies mit GNUs ps (Linux) funktioniert, nicht jedoch mit BSD ps.
Josh
Dies ist auch bei GNU ps falsch. ps -C <command>entspricht dem genauen Befehl. Wenn sie mit den verwendeten aoder xOptionen wird es alle Prozesse berichten, da aund xListe Prozesse zusätzlich zu dem Satz von durch andere Mittel angepasst Prozesse.
Animismus
@ Animism True. Danke, ich habe es behoben.
Andreas Frische
Dies funktioniert nur, wenn der Prozessname genau angegeben ist. Es funktioniert nicht für eine teilweise Übereinstimmung, z. B. logindfür systemd-logindoder zum Abgleichen von Argumenten.
Acumenus
4

Noch eine Alternative :

ps -fC terminal

Hier die Optionen:

 -f        does full-format listing. This option can be combined
           with many other UNIX-style options to add additional
           columns. It also causes the command arguments to be
           printed. When used with -L, the NLWP (number of
           threads) and LWP (thread ID) columns will be added. See
           the c option, the format keyword args, and the format
           keyword comm.

 -C cmdlist     Select by command name.
                This selects the processes whose executable name is
                given in cmdlist.
TaXXoR
quelle
6
Ein kleiner Nachteil, der nicht wirklich mit der Frage von OP zusammenhängt, ist, dass dies Ihnen keine Dinge wie Tomcat zeigt, das tatsächlich als Java mit einer Wäscheliste von Argumenten ausgeführt wird.
Charles Wood
-COption wurde bereits in der Antwort von @Andreas Frishe vorgeschlagen, die über anderthalb Jahre zuvor veröffentlicht wurde…
Piotr Dobrogost
3

Die Verwendung von Klammern zum Umgeben eines Zeichens im Suchmuster schließt den grepVorgang aus, da er nicht den passenden regulären Ausdruck enthält.

$ ps ax | grep 'syslogd'
   16   ??  Ss     0:09.43 /usr/sbin/syslogd
18108 s001  S+     0:00.00 grep syslogd

$ ps ax | grep '[s]yslogd'
   16   ??  Ss     0:09.43 /usr/sbin/syslogd

$ ps ax | grep '[s]yslogd|grep'
   16   ??  Ss     0:09.43 /usr/sbin/syslogd
18144 s001  S+     0:00.00 grep [s]yslogd|grep
Tantechilada
quelle
3

Haftungsausschluss: Ich bin der Autor dieses Tools, aber ...

Ich würde px verwenden :

~ $ px atom
  PID COMMAND          USERNAME   CPU RAM COMMANDLINE
14321 crashpad_handler walles   0.01s  0% /Users/walles/Downloads/Atom.app/Contents/Frameworks/Electron Framework.framework/Resources/crashpad_handler --database=
16575 crashpad_handler walles   0.01s  0% /Users/walles/Downloads/Atom.app/Contents/Frameworks/Electron Framework.framework/Resources/crashpad_handler --database=
16573 Atom Helper      walles    0.5s  0% /Users/walles/Downloads/Atom.app/Contents/Frameworks/Atom Helper.app/Contents/MacOS/Atom Helper --type=gpu-process --cha
16569 Atom             walles   2.84s  1% /Users/walles/Downloads/Atom.app/Contents/MacOS/Atom --executed-from=/Users/walles/src/goworkspace/src/github.com/github
16591 Atom Helper      walles   7.96s  2% /Users/walles/Downloads/Atom.app/Contents/Frameworks/Atom Helper.app/Contents/MacOS/Atom Helper --type=renderer --no-san

Abgesehen davon, dass Prozesse mit einer sinnvollen Befehlszeilenschnittstelle gefunden werden, werden auch viele andere nützliche Dinge ausgeführt, weitere Details auf der Projektseite .

Funktioniert unter Linux und OS X, einfach zu installieren:

curl -Ls https://github.com/walles/px/raw/python/install.sh | bash
Johan Walles
quelle
0

Abhängig vom endgültigen Anwendungsfall möchten Sie häufig stattdessen Awk bevorzugen.

ps aux | awk '/[t]erminal/'

Dies gilt insbesondere dann, wenn Sie so etwas haben

ps aux | grep '[t]erminal' | awk '{print $1}'  # useless use of grep!

wo offensichtlich der reguläre Ausdruck trivial in das Awk-Skript einbezogen werden kann:

ps aux | awk '/[t]erminal/ { print $1 }'

Aber wirklich, erfinden Sie das nicht selbst neu. pgrepund Freunde sind schon lange da und behandeln diesen gesamten Problembereich viel besser als die meisten Ad-hoc-Neuimplementierungen.

Tripleee
quelle
-2

Eine andere Möglichkeit besteht darin, Ihre .bash_profile(oder eine andere Datei, in der Sie Bash-Aliase behalten) zu bearbeiten , um eine Funktion zu erstellen, die 'grep' aus den Ergebnissen herausgreift.

function mygrep {
grep -v grep | grep --color=auto $1
}

alias grep='mygrep'

Das grep -v grepmuss zuerst sein, sonst --color=autofunktioniert es aus irgendeinem Grund nicht.

Dies funktioniert, wenn Sie bash verwenden. Wenn Sie eine andere Shell YMMV verwenden.

FlyingCodeMonkey
quelle
1
Was ist mit dem Alias und der Funktion? Tun Sie es einfach function grep { command grep -v grep | command grep --color=auto "$@"; }(beachten Sie auch die Korrektur des Arguments und das Zitieren). Dies wird jedoch dadurch unterbrochen, dass ein Nichtaufruf psvon grepnicht mehr funktioniert (die Argumente werden falsch übergeben). Eine viel nützlichere Funktion wäre jedenfalls eine, die den regulären Ausdruck so ändert, dass er nicht mit sich selbst übereinstimmt, anstatt separat grepaus den grepErgebnissen herauszufiltern . Und natürlich ist es nicht sehr produktiv, neue Lösungen für ein Problem zu erfinden, das vor Jahrzehnten angemessen gelöst wurde.
Tripleee