¿Por qué "ps aux | grep x "dar mejores resultados que" pgrep x "?

82

Acabo de probar el siguiente comando en mi Ubuntu, no muestra nada:

pgrep php5

¿No debería devolver el id de proceso de php5 (que hace el siguiente comando) ?:

ps aux | grep php5

Entonces, ¿cuál es la diferencia entre estos dos comandos?

xczzhh
fuente

Respuestas:

75

ps auxincluye la línea de comando completa (ruta y parámetros), mientras que pgrep solo mira los primeros 15 caracteres de los nombres del ejecutable

ps auxdevuelve la línea de comando completa de cada proceso, mientras pgrepsolo mira los nombres de los ejecutables.

Eso significa que la salida grepping ps aux coincidirá con cualquier cosa que ocurra en la ruta o los parámetros de un proceso 'binario: por ejemplo,'

  • ps aux | grep php5 coincidirá /usr/share/php5/i-am-a-perl-script.pl
  • pero pgrep php5no lo hará

Tome un ejemplo de mi sistema, solo usaremos python en lugar de php5:

  • ps aux | grep python Nos da:
izx 2348 0.0 0.7 514928 15644? Sl Jun24 0:00 / usr / bin / python / usr / lib / unity-lens-video / unity-lens-video
izx 2444 0.0 0.9 547392 18864? Sl Jun24 0:01 / usr / bin / python / usr / lib / unity-scope-video-remote / unity-scope-video-remote
raíz 2805 0.0 0.5 95436 12204? S Jun24 0:00 / usr / bin / python / usr / lib / system-service / system-service-d
izx 6272 0.0 2.9 664400 60320? SNl Jun24 1:16 / usr / bin / python / usr / bin / update-manager --no-focus-on-map
raíz 11729 0.0 0.9 180508 19516? S Jun25 0:00 python / usr / lib / software-properties / software-properties-dbus
  • Pero pgrep pythonsolo devuelve 11729, lo que verá en la lista anterior es:
raíz 11729 0.0 0.9 180508 19516? S Jun25 0:00 python / usr / lib / software-properties / software-properties-dbus
ish
fuente
3
"pgrep -l" también trunca el proceso a 15 caracteres, lo que probablemente sea un error, pero ha sido así durante siglos
Thorsen
1
Bueno, está en launchpad como un error ascendente a partir de 2008 :) "comando truncado superior y ps después de 15 caracteres" bugs.launchpad.net/ubuntu/+source/procps/+bug/295876
Thorsen
2
Ah, esto lo explica, desde el comentario # 3: Esto se debe al hecho de que algunos procedimientos de procs obtienen el nombre del comando de /proc/<pid>/statpero no de/proc/<pid>/cmdline . OK, @Thorsen, ganas el repelente de insectos, es un error: P
ish
2
@xczzhh pgrepno es un comando irrazonable. Funciona bien y según lo diseñado. El problema es que simplemente te faltaba una opción cuando la ejecutas, no puedes culparlo pgreppor eso. El uso ps aux | grep xxxno es confiable, por lo que es necesario que los piratas se filtren grepdesde la salida y podrían dar falsos positivos como con ps aux | grep root.
jlliagre
1
Esto debería estar en un anti-drogas comercial, los creadores de herramientas de bash estaban tan ardieron con LSD que pensaban que este tipo de cosas estaban bien diseñados
Andy Ray
78

El ps aux | grep xcomando da "mejores" resultados que pgrep xesencialmente porque le falta una opción con este último.

Simplemente use la -fopción para pgrepbuscar la línea de comando completa y no solo el nombre del proceso, que es su comportamiento predeterminado, por ejemplo:

pgrep -f php5

A diferencia de la ps | grepconstrucción con la que necesita filtrar la greplínea o usar trucos de patrones, pgrepsimplemente no se seleccionará por diseño.

Además, si su patrón aparece en la ps USERcolumna, obtendrá procesos no deseados en la salida, pgrepno sufrirá este defecto.

Si desea detalles completos en lugar de solo los pids, puede usar:

ps wup $(pgrep -f python)

que es más simple y más confiable que

ps aux | grep python | grep -v grep

o

ps aux | grep p[y]thon
jlliagre
fuente
3
Agregue también la opción -a( --list-full) si desea ver la línea de comando completa y no solo el pid. (El pgrep más viejo no tenía -a, hizo esto-fl .)
Beni Cherniavsky-Paskin
1
La pregunta original era preguntar sobre la diferencia, pero esto en realidad nos da a aquellos de nosotros que tratamos pgrepde jugar bien la solución. +1
2rs2ts
@ 2rs2ts Gracias, de hecho me faltaba responder a la pregunta formulada. Corregido ahora.
jlliagre
En algunos casos, cuando los programas se modifican /proc/self/cmdlinepara ser "descriptivos", pgrep -fa rubyno coincidirán, por ejemplo. puma 3.3.0 (tcp://localhost:3000) [MIQ: Web Server Worker], mientras que el "tonto" lo pgrep -a rubyhará. No estoy seguro si este último también puede ser engañado.
Beni Cherniavsky-Paskin
@ BeniCherniavsky-Paskin Supongo que podría haber sido un comentario a la pregunta, ya que se aplica a ambos pgrepy ps.
Franklin Yu
3
diff <(ps aux|grep x) <(pgrep x) # :)
Thorsen
fuente
12
Esto puede responder la respuesta a la pregunta, pero quizás pueda expandir su respuesta para explicar lo que hace este comando de una línea.
fossfreedom
1

En este momento, psdará una salida más completa que la pgep -fpgrep se limita a los primeros 4.096 caracteres (a menudo afecta a los usuarios de Java que buscan la clase de entrada de un programa Java con una ruta de clase larga). El seguimiento del error es: https://gitlab.com/procps-ng/procps/issues/86

Arcilla B.
fuente
Busqué por siempre esto.
Tresf