为什么pidof和pgrep的行为有所不同?


8

我有一个初始化脚本,/etc/init.d/myservice用于初始化这样的服务:

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

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

当我尝试停止该服务时,这是输出:

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

这是预期的吗?为什么pidof只返回要停止的服务的正确PID,并pgrep返回服务PID和init脚本的PID?我可以依靠它pidof始终忽略初始化脚本中的PID吗?

Answers:


7

pidof =查找正在运行的程序的进程ID

Pidof查找命名程序的进程ID(PID)。它在标准输出上打印这些id。该程序在运行级更改脚本中使用的某些系统上,特别是当系统具有类似于System-V的rc结构时。

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

pgrep =根据名称和其他属性查找或发信号通知进程,pgrep查找当前正在运行的进程并列出与选择标准匹配的进程ID。

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

pgrep,(p)=进程,grep= grep打印匹配的行

想更多地了解pgrep和pidof?只需在终端运行

# man pidof
# man pgrep

1
啊哈,那为什么pidof不返回10001,因为程序是sh,不?
Pigueiras

是的,您是对的
Babin Lonston 2014年

0

我认为您不应该依赖它pidof,它可能导致您的程序失败。一个简单的supervisord程序示例:

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

您可以看到,supervisord实际上是由python解释器调用的,导致pidof失败:

#! /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')()
    )

但是在这种情况下,我可以依靠它吗?,我没有使用解释器来执行程序(它是可执行的二进制文件)。
Pigueiras

当然。但是我认为好的方法是使用killproc。为什么你,而你haved使用不使用这个daemonstart功能?
cuonglm

因为我想获取PID来杀死进程的子进程,所以我一直在使用它killproc来杀死进程本身。
Pigueiras 2014年

你为什么要那样做?如果您杀死parent process,它child process也会死。
cuonglm


0

pidof除非您包含该-x选项,否则该命令将忽略脚本。同样,在pidof命令中包含完整路径也是最安全的,如下所示:

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

这样可以最大程度地减少匹配其他过程的机会。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.