¿Por qué pidof y pgrep se comportan de manera diferente?

8

Tengo un script de inicio /etc/init.d/myservicepara inicializar un servicio como este:

...
start() {
  ...
  daemon /usr/sbin/myservice
  ...
}

stop() {
  ...
  pgrep myservice
  pidof myservice
  ps -ef | grep myservice
  ...
}

Y cuando trato de detener el servicio, este es el resultado:

10000 10001
10000
root      10000     1  0 09:52 ?        00:00:02 /usr/sbin/myservice
root      9791   9788  0 10:06 pts/1    00:00:00 /bin/sh /sbin/service myservice stop
root      10001  9791  1 10:06 pts/1    00:00:00 /bin/sh /etc/init.d/myservice stop 
root      9805   9796  0 10:06 pts/1    00:00:00 grep myservice

¿Se espera esto? ¿Por qué pidofdevuelve solo el PID correcto del servicio que quiero detener y pgrepdevuelve el PID del servicio y el PID del script de inicio? ¿Puedo confiar en que pidofsiempre se ignorará el PID del script de inicio?

Pigueiras
fuente

Respuestas:

7

pidof = encuentra el ID de proceso de un programa en ejecución

Pidof encuentra la identificación del proceso (pids) de los programas nombrados. Imprime esas identificaciones en la salida estándar. Este programa está en algunos sistemas utilizados en scripts de cambio de nivel de ejecución, especialmente cuando el sistema tiene una estructura rc similar a System-V.

sysadmin@codewarden:~$ pidof apache2
5098 5095 5094 5092

pgrep = buscar o señalar procesos basados ​​en el nombre y otros atributos, pgrep revisa los procesos que se ejecutan actualmente y enumera los ID de proceso que coinciden con los criterios de selección.

sysadmin@codewarden:~$ pgrep apache2
5092
5094
5095
5098

pgrep, (p) = proceso, grep= grep imprime las líneas coincidentes

¿Quieres saber más sobre pgrep y pidof? Solo corre en la terminal como

# man pidof
# man pgrep
Babin Lonston
fuente
1
Ajá, por eso pidofno regresa 10001, porque el programa sí sh, ¿no?
Pigueiras
sí, tienes razón
Babin Lonston
0

Creo que no debe confiar pidof, puede hacer que su programa falle. Un ejemplo simple con el supervisordprograma:

% cuonglm at ~
% ps -ef | grep supervisord
root      8512     1  0 16:53 ?        00:00:00 /usr/bin/python /usr/bin/supervisord
cuonglm   8584  7688  0 17:00 pts/0    00:00:00 grep --color=auto supervisord
% cuonglm at ~
% pidof supervisord
% cuonglm at ~
% 

Como puede ver, el supervisordintérprete de python lo llama realmente, hace pidofque falle:

#! /usr/bin/python                                                            
# EASY-INSTALL-ENTRY-SCRIPT: 'supervisor==3.0a8','console_scripts','supervisord'
__requires__ = 'supervisor==3.0a8'                                            
import sys                                                                    
from pkg_resources import load_entry_point                                    

if __name__ == '__main__':                                                    
    sys.exit(                                                                 
        load_entry_point('supervisor==3.0a8', 'console_scripts', 'supervisord')()
    )
Cuonglm
fuente
Pero en este caso puedo confiar en él, ¿no ?, no estoy usando un intérprete para ejecutar el programa (es un binario ejecutable).
Pigueiras
Por supuesto. Pero creo que la buena manera es el uso killproc. ¿Por qué no usa esto mientras lo ha usado daemonen la startfunción?
Cuonglm
Debido a que quiero obtener el PID para matar a los hijos del proceso, lo estaba usando killprocpara matar el proceso en sí.
Pigueiras
¿Por qué debes hacer eso? si matas parent process, child processtambién morirá su voluntad.
Cuonglm
No, no lo creo: stackoverflow.com/questions/8533377/…
Pigueiras
0

El pidofcomando ignora los scripts a menos que incluya la -xopción. Además, es más seguro incluir la ruta completa en el comando pidof, como en:

killme=$(pidof -x /usr/bin/supervisord)
      *instead of*
killme=$(pidof -x supervisord)

Esto minimiza las posibilidades de igualar algún otro proceso.

John Hascall
fuente