Más elegante "ps aux | grep -v grep "

177

Cuando reviso la lista de procesos y 'selecciono' aquellos que son interesantes para mí, el grepmismo también se incluye en los resultados. Por ejemplo, para enumerar terminales:

$ 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

Normalmente uso ps aux | grep something | grep -v greppara deshacerme de la última entrada ... pero no es elegante :)

¿Tiene un truco más elegante para resolver este problema (aparte de envolver todo el comando en un script separado, que tampoco está mal)

Jakub M.
fuente
44
Por lo que vale, esta es una antigua pregunta frecuente. Vea el ítem 3.10 en faqs.org/faqs/unix-faq/faq/part3
tripleee
1
Gracias por referencia Ese es su método:ps ux | awk '/name/ && !/awk/ {print $2}'
Jakub M.
¿Qué está grep -v grephaciendo la parte?
Jwan622
2
@ Jwan622 grep -v grepexcluye grepde resultados grep. Si grep se usa en combinación con ps, entonces también se mostrará el proceso grep (con argumentos grep), abarrotando sus resultados. grep -v grep es una forma común de evitar eso
Eugene Platonov

Respuestas:

282

La técnica habitual es esta:

ps aux | egrep '[t]erminal'

Esto coincidirá con las líneas que contienen terminal, lo egrep '[t]erminal'que no. También funciona en muchos sabores de Unix.

Johnsyweb
fuente
1
Esto funciona para mí para una cadena arbitraria, pero no para un nombre de usuario, por ejemplo ps aux | grep '[r]oot'. ¿Alguien sabe por qué?
kxsong
2
@kxsong: | grep '[t]erminal'selecciona cualquier línea que contenga la palabra 'terminal' sin poner la palabra 'terminal' en la lista de procesos. ¿Con qué estás tratando de lograr | grep '[r]oot'y cómo no funciona? Es probable que haya una mejor solución.
Johnsyweb
3
Corrígeme si me equivoco, pero esto también debería funcionar en cualquier posición del personaje greptado: ps aux | grep "te [r] minal"
meso_2600
2
truco brillante (creo que debería llamarlo así, ya que los autores aux / grep probablemente no pensaron en este escenario.)
Michael Trouw
2
@JamieJag: Bueno ... como dije en mi publicación, grep '[t]erminal'coincidirá con las líneas que contienen terminal. La salida de ps auxtendrá una línea con grep '[t]erminal'(con corchetes), que no contiene la cadena terminal(sin la misma).
Johnsyweb
57

Usa pgrep . Es mas confiable.

Polvo oscuro
fuente
pgrepno funcionaría si busco, por ejemplops aux | grep 'ssh options'
Jakub M.
12
Jakub M .: ¿Y qué pgrep -f?
hillu
44
@ jakub-m De manera predeterminada, pgrepsolo coincide con el patrón con el nombre del proceso. Para hacer coincidir todo el comando, use la -fbandera.
bluecollarcoder
3
pgrepsolo devuelve ID de proceso.
Melab
1
las versiones anteriores tomaron pgrep -fl(pero no podían ver el cmdline completo sin -fcoincidir con el cmdline completo, detalles: serverfault.com/a/619788/44183 ). Pero sí, si necesita otra información además de pid, cmdline, la necesita ps. Puede combinarlos:ps -p $(pgrep -f foo)
Beni Cherniavsky-Paskin
29

Esta respuesta se basa en una pgrep respuesta previa . También se basa en otra respuesta que combina el uso de pscon pgrep. Aquí hay algunos ejemplos de capacitación pertinentes:

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

Lo anterior se puede usar como una función :

$ 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

Comparar con usar pscon grep. La útil fila de encabezado no se imprime:

$  ps aux | grep [s]shd
root      1902  0.0  0.1  82560  3580 ?        Ss   Oct20   0:00 /usr/sbin/sshd -D
Acumenus
fuente
Ver github.com/blueyed/oh-my-zsh/blob/… (pero es específico de Zsh).
azulado
@blueyed, he actualizado la respuesta con la definición de la función bash.
Acumenus
Tenga en cuenta también la -dopción de especificar un separador; Por ejemplops -fp$(pgrep -d , getty)
Toby Speight
1
Uso esto: tenga en ps uxp `pgrep <process>` cuenta que pdebe ser el último parámetro (es decir, puxno funcionará)
KFL
9

Puede filtrar en el comando ps, por ejemplo

ps u -C gnome-terminal

(o busque / proc con find, etc.)

Andreas Frische
fuente
1
Tenga en cuenta que esto funciona con la ps de GNU (Linux), pero no con la ps de BSD.
Josh
Esto es incorrecto incluso con GNU ps. ps -C <command>coincidirá con el comando exacto. Cuando se utiliza con los ao xlas opciones que reportará todos los procesos, pues a, y xla lista de procesos , además de la serie de procesos coincidentes por otros medios.
Animismo
@Animism True. Gracias, lo arreglé.
Andreas Frische
Esto funciona solo si el nombre del proceso se especifica exactamente. No funciona para una coincidencia parcial, por ejemplo , logindpara systemd-logind, o para hacer coincidir argumentos.
Acumenus
4

Una alternativa más :

ps -fC terminal

Aquí las opciones:

 -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
fuente
66
Un inconveniente menor, y uno que no está realmente relacionado con la pregunta de OP, es que esto no le mostrará cosas como Tomcat, que en realidad se ejecuta como java con una larga lista de argumentos.
Charles Wood
-Cla opción ya fue sugerida en la respuesta de @Andreas Frishe publicada más de un año y medio antes ...
Piotr Dobrogost
3

El uso de corchetes para rodear un carácter en el patrón de búsqueda excluye el grepproceso ya que no contiene la expresión regular coincidente.

$ 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
fuente
3

Descargo de responsabilidad: soy el autor de esta herramienta, pero ...

Yo usaría 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

Excepto para encontrar procesos con una interfaz de línea de comandos sensible, también hace muchas otras cosas útiles, más detalles en la página del proyecto .

Funciona en Linux y OS X, se instala fácilmente:

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

Dependiendo del caso de uso final, a menudo prefieres Awk en su lugar.

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

Esto es particularmente cierto cuando tienes algo como

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

donde obviamente la expresión regular se puede factorizar en la secuencia de comandos Awk trivialmente:

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

Pero en realidad, no reinventes esto tú mismo. pgrepy amigos han existido por mucho tiempo y manejan todo este espacio problemático mucho mejor que la mayoría de las reimplementaciones ad hoc.

tripleee
fuente
-2

Otra opción es editar su .bash_profile(u otro archivo en el que mantenga los alias bash) para crear una función que elimine los resultados.

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

alias grep='mygrep'

El grep -v greptiene que ser el primero de lo contrario su --color=autovoluntad no funciona por alguna razón.

Esto funciona si estás usando bash; si está usando un shell diferente YMMV.

FlyingCodeMonkey
fuente
1
¿Qué pasa con el alias y la función? Solo hazlo function grep { command grep -v grep | command grep --color=auto "$@"; }(también ten en cuenta la solución del argumento y la cita). Sin embargo, esto se rompe porque cualquier no psinvocación de grepya no funcionará (los argumentos se pasan incorrectamente). De todos modos, una función mucho más útil sería aquella que modifica la expresión regular para que no coincida, en lugar de filtrar greplos grepresultados por separado. Y, por supuesto, inventar nuevas soluciones a un problema que se resolvió adecuadamente hace décadas no es muy productivo.
tripleee