Plus élégant «ps aux | grep -v grep »

178

Quand je vérifie la liste des processus et «grep» ceux qui sont intéressants pour moi, le greplui-même est également inclus dans les résultats. Par exemple, pour lister les terminaux:

$ 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

Normalement j'utilise ps aux | grep something | grep -v greppour me débarrasser de la dernière entrée ... mais ce n'est pas élégant :)

Avez-vous un hack plus élégant pour résoudre ce problème (à part envelopper toutes les commandes dans un script séparé, ce qui n'est pas mal non plus)

Jakub M.
la source
4
Pour ce que ça vaut, c'est une ancienne FAQ. Voir l'article 3.10 sur faqs.org/faqs/unix-faq/faq/part3
tripleee
1
Merci pour la référence. C'est leur méthode:ps ux | awk '/name/ && !/awk/ {print $2}'
Jakub M.
Que fait la grep -v greppartie?
Jwan622
2
@ Jwan622 grep -v grepexclut grepdes résultats grep. Si grep est utilisé en combinaison avec ps, alors le processus grep (avec les arguments grep) sera également affiché, encombrant vos résultats. grep -v grep est un moyen courant d'éviter cela
Eugene Platonov

Réponses:

283

La technique habituelle est la suivante:

ps aux | egrep '[t]erminal'

Cela correspondra aux lignes contenant terminal, ce qui egrep '[t]erminal'n'est pas le cas! Il fonctionne également sur de nombreuses versions d'Unix.

Johnsyweb
la source
1
Cela fonctionne pour moi pour une chaîne arbitraire, mais pas pour un nom d'utilisateur, par exemple ps aux | grep '[r]oot'. Quelqu'un sait-il pourquoi?
kxsong
2
@kxsong: | grep '[t]erminal'sélectionne n'importe quelle ligne contenant le mot 'terminal' sans mettre le mot 'terminal' dans la liste des processus. Avec | grep '[r]oot'quoi essayez-vous et comment cela ne fonctionne-t-il pas? Il y a probablement une meilleure solution.
Johnsyweb
3
Corrigez-moi si je me trompe, mais cela devrait également fonctionner sur n'importe quelle position du caractère grepped: ps aux | grep "te [r] minal"
meso_2600
2
hack brillant (je pense que je devrais l'appeler ainsi, puisque les auteurs aux / grep n'ont probablement pas pensé à ce scénario.)
Michael Trouw
2
@JamieJag: Eh bien ... comme je l'ai dit dans mon message, grep '[t]erminal'correspondra aux lignes contenant terminal. La sortie de ps auxaura une ligne avec grep '[t]erminal'(avec les crochets), qui ne contient pas la chaîne terminal(sans la même chose).
Johnsyweb
57

Utilisez pgrep . C'est plus fiable.

DarkDust
la source
pgrepne fonctionnera pas si je recherche par exempleps aux | grep 'ssh options'
Jakub M.
12
Jakub M.: Et pgrep -f?
hillu
4
@ jakub-m Par défaut, pgrepcorrespond uniquement le modèle au nom du processus. Pour correspondre à l'ensemble de la commande, utilisez l' -findicateur.
bluecollarcoder
3
pgreprenvoie uniquement les ID de processus.
Melab
1
les anciennes versions prenaient pgrep -fl(mais ne pouvaient pas voir la pleine cmdline sans -fcorrespondre à la pleine cmdline, détails: serverfault.com/a/619788/44183 ). Mais oui, si vous avez besoin d'autres informations à côté de pid, cmdline, vous avez besoin ps. Peut les combiner:ps -p $(pgrep -f foo)
Beni Cherniavsky-Paskin
29

Cette réponse s'appuie sur une pgrep réponse antérieure . Il s'appuie également sur une autre réponse combinant l'utilisation de psavec pgrep. Voici quelques exemples de formation pertinents:

$ 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]

Ce qui précède peut être utilisé comme une fonction :

$ 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

Comparez avec l'utilisation psde grep. La ligne d'en-tête utile n'est pas imprimée:

$  ps aux | grep [s]shd
root      1902  0.0  0.1  82560  3580 ?        Ss   Oct20   0:00 /usr/sbin/sshd -D
Acumenus
la source
Voir github.com/blueyed/oh-my-zsh/blob/… (mais c'est spécifique à Zsh).
blueyed
@blueyed, j'ai mis à jour la réponse avec la définition de la fonction bash.
Acumenus
Notez également l' -doption pour spécifier un séparateur; par exempleps -fp$(pgrep -d , getty)
Toby Speight
1
J'utilise ceci: ps uxp `pgrep <process>` Notez que cela pdoit être le dernier paramètre (c'est-à-dire, puxne fonctionnera pas)
KFL
Cela ne colore pas le nom du processus de recherche comme le grepfait
alper
9

Vous pouvez filtrer dans la commande ps, par exemple

ps u -C gnome-terminal

(ou recherchez dans / proc avec find etc.)

Andreas Frische
la source
1
Notez que cela fonctionne avec le ps de GNU (Linux), mais pas avec le ps de BSD.
Josh
Ceci est incorrect même avec GNU ps. ps -C <command>correspondra à la commande exacte. Lorsqu'il est utilisé avec les options aou x, il signale tous les processus, car aet xrépertorie les processus en plus de l'ensemble des processus mis en correspondance par d'autres moyens.
Animisme
@Animism True. Merci, je l'ai réparé.
Andreas Frische
Cela ne fonctionne que si le nom du processus est spécifié exactement. Cela ne fonctionne pas pour une correspondance partielle, par exemple logindpour systemd-logind, ou pour faire correspondre des arguments.
Acumenus
4

Encore une alternative :

ps -fC terminal

Voici les options:

 -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
la source
6
Un inconvénient mineur, et qui n'est pas vraiment lié à la question d'OP, est que cela ne vous montrera pas des choses comme Tomcat, qui est en fait exécuté en java avec une longue liste d'arguments.
Charles Wood
-Coption a déjà été suggérée dans la réponse de @Andreas Frishe publiée plus d'un an et demi plus tôt…
Piotr Dobrogost
4

Avertissement: je suis l'auteur de cet outil, mais ...

J'utiliserais px :

~ $ 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

Sauf pour trouver des processus avec une interface de ligne de commande sensible, il fait également beaucoup d'autres choses utiles, plus de détails sur la page du projet .

Fonctionne sous Linux et OS X, s'installe facilement:

curl -Ls https://github.com/walles/px/raw/python/install.sh | bash
Johan Walles
la source
3

L'utilisation de crochets pour entourer un caractère dans le modèle de recherche exclut le grepprocessus car il ne contient pas l'expression régulière correspondante.

$ 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
auntchilada
la source
0

Selon le cas d'utilisation ultime, vous préférez souvent Awk à la place.

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

Cela est particulièrement vrai lorsque vous avez quelque chose comme

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

où, évidemment, l'expression régulière peut être prise en compte dans le script Awk de manière triviale:

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

Mais vraiment, ne réinventez pas cela vous-même. pgrepet les amis existent depuis longtemps et gèrent bien mieux que la plupart des réimplémentations ad hoc.

tripleee
la source
-3

Une autre option consiste à éditer votre .bash_profile(ou un autre fichier dans lequel vous conservez les alias bash) pour créer une fonction qui grep 'grep' hors des résultats.

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

alias grep='mygrep'

Le grep -v grepdoit être le premier sinon vous --color=autone fonctionnerez pas pour une raison quelconque.

Cela fonctionne si vous utilisez bash; si vous utilisez un autre shell YMMV.

FlyingCodeMonkey
la source
1
Qu'est-ce que l'alias et la fonction? Faites simplement function grep { command grep -v grep | command grep --color=auto "$@"; }(notez également la correction de l'argument et la citation). Cependant, cela est interrompu en ce que toute non- psinvocation de grepne fonctionnera plus (les arguments sont transmis de manière incorrecte). Quoi qu'il en soit, une fonction beaucoup plus utile serait celle qui modifie l'expression rationnelle pour qu'elle ne corresponde pas à elle-même, plutôt que de filtrer greples greprésultats séparément. Et bien sûr, inventer de nouvelles solutions à un problème qui a été correctement résolu il y a des décennies n'est pas très productif.
tripleee