pidof 和 pgrep 有什么区别?

pidof 和 pgrep 有什么区别?

当我使用这些命令中的任何一个并以参数作为进程名称时,它们都返回完全相同的数字。它们是相同的命令吗?它们是执行相同操作的两个不同命令吗?其中一个是另一个的别名吗?

pidof firefox
pgrep firefox

答案1

这些程序pgrep和程序pidof并不完全相同,但它们非常相似。例如:

$ pidof 'firefox'
5696
$ pgrep '[i]ref'
5696
$ pidof '[i]ref'
$ printf '%s\n' "$?"
1

正如您所看到的,pidof未能找到 的匹配项[i]ref。这是因为pidof program返回与名为 的程序关联的所有进程 ID 的列表program。另一方面,pgrep re返回与名称与正则表达式匹配的程序关联的所有进程 ID 的列表re

在最基本的形式中,等价实际上是:

$ pidof 'program'
$ pgrep '^program$'

作为另一个具体示例,请考虑:

$ ps ax | grep '[w]atch'
   12 ?        S      0:04 [watchdog/0]
   15 ?        S      0:04 [watchdog/1]
   33 ?        S<     0:00 [watchdogd]
18451 pts/5    S+     0:02 watch -n600 tail log-file
$ pgrep watch
12
15
33
18451
$ pidof watch
18451

答案2

Fox 提到pgrep使用正则表达式进行搜索,而 while 则pidof没有。

pgrep还有更多可用选项:

  • -u "$UID"可以仅匹配属于当前用户的进程。
  • 您可以使用它--parent找到给定进程的子进程。
  • 您可以选择一个--oldest--newest多个匹配进程。
  • ...以及手册页上列出的其他各种...

让我们找出每个进程属于哪个包(在 apt 系统上):

$ dpkg -S "$(which pidof)"
sysvinit-utils: /bin/pidof

$ dpkg -S "$(which pgrep)"
procps: /usr/bin/pgrep

在 pacman 系统上:

$ pacman -Qo "$(which pidof)"
/usr/bin/pidof is owned by procps-ng 3.3.17-1

$ pacman -Qo "$(which pgrep)"
/usr/bin/pgrep is owned by procps-ng 3.3.17-1

在 RPM 系统上:

$ rpm -qf "$(which pidof)"
... ?

答案3

请注意:pidof可以将最后一个斜杠之后的所有内容视为program name

fang@debian:~$ ps -ax | grep k3s | head -n1
    528 ?        Ssl  634:37 /usr/local/bin/k3s server
fang@debian:~$ pgrep k3s
528
fang@debian:~$ pidof k3s
fang@debian:~$ pidof /usr/local/bin/k3s
fang@debian:~$ pidof '/usr/local/bin/k3s server'
528
fang@debian:~$ pidof 'k3s server'
528

更新:正如 Stéphane Chazelas 所说,pidof实际上匹配任何:

  • Name:领域在/proc/pid/status
  • 第一个参数/proc/pid/cmdline
  • 第一个参数的基本名称/proc/pid/cmdline

在大多数情况下,每个 arg 后面应该有一个NUL。例如。睡觉:

fang@debian:~$ sleep infinity &
[1] 2076966
fang@debian:~$ pidof sleep
2076966
fang@debian:~$ xxd /proc/2076966/cmdline
00000000: 736c 6565 7000 696e 6669 6e69 7479 00    sleep.infinity.
fang@debian:~$ head -n1 /proc/2076966/status
Name:   sleep

它有点特殊,因为argv[0]包含空格:

fang@debian:~$ ls -l /usr/local/bin/k3s
-rwxr-xr-x 1 root root 54001664  7月  3 20:16 /usr/local/bin/k3s
fang@debian:~$ head -n1 /proc/528/status
Name:   k3s-server
fang@debian:~$ head -n1 /proc/528/cmdline && echo
/usr/local/bin/k3s server
fang@debian:~$ xxd /proc/528/cmdline 
00000000: 2f75 7372 2f6c 6f63 616c 2f62 696e 2f6b  /usr/local/bin/k
00000010: 3373 2073 6572 7665 7200 0000 0000 0000  3s server.......

总之,要获取其 pid,您可以:

fang@debian:~$ pgrep k3s-server
528
fang@debian:~$ pidof k3s-server
528
fang@debian:~$ pidof 'k3s server'
528

你不能:

fang@debian:~$ pgrep 'k3s server'

因为它只匹配

  • Name:领域在/proc/pid/status
  • (...)(好像和里面的部分是一样的/proc/pid/stat吧?)

相关内容