菜鸟科技网

pgrep命令如何精准查找进程PID?

pgrep 是一个在 Linux 和 Unix-like 系统中非常实用的命令行工具,它的名字来源于 "process grep"(进程 grep),正如其名,它的作用是根据进程的属性(如名称、用户ID、进程组ID等)来查找匹配的进程的 ID (PID)

pgrep命令如何精准查找进程PID?-图1
(图片来源网络,侵删)

pgrep 就像是 psgrep 的结合体,但它更简洁、更强大。


为什么需要 pgrep

pgrep 出现之前,我们通常使用 psgrep 的组合来查找进程 ID,

# 查找名为 "nginx" 的所有进程的 PID
ps aux | grep nginx | grep -v grep | awk '{print $2}'

这条命令虽然能工作,但存在几个问题:

  • 冗长:需要组合多个命令 (ps, grep, awk)。
  • 脆弱:如果进程名中包含 "grep",或者 ps 的输出格式发生变化(比如不同发行版的 ps 默认格式不同),命令就会出错或失效。
  • 效率低:需要生成整个进程列表,然后通过管道传递给 grep 进行过滤。

pgrep 正是为了解决这些问题而生,它直接与内核通信,只返回匹配的 PID,更加高效和可靠。

pgrep命令如何精准查找进程PID?-图2
(图片来源网络,侵删)

pgrep 的基本语法

pgrep [选项] 模式
  • 模式:通常是进程的名称,也可以是其他属性。
  • [选项]:用于控制匹配规则和输出格式。

常用选项和示例

1 基本用法:按进程名查找

这是 pgrep 最常见的用法。

# 查找所有名为 "sshd" 的进程的 PID
pgrep sshd

如果找到多个匹配的进程,pgrep 会默认将它们的 PID 以空格分隔打印在一行上。

示例输出:

1234 5678 9012

2 -l (list names) 选项:显示进程名

在输出 PID 的同时,也显示进程名。

pgrep命令如何精准查找进程PID?-图3
(图片来源网络,侵删)
# 查找 "sshd" 进程,并显示其 PID 和进程名
pgrep -l sshd

示例输出:

1234 sshd
5678 sshd
9012 sshd

3 -f (full) 选项:匹配完整命令行

默认情况下,pgrep 只匹配进程名,使用 -f 选项可以匹配整个命令行(ps 命令输出的最后一列),这对于查找带有参数的进程非常有用。

# 查找正在运行 "nginx -g daemon off;" 的进程
# 如果只用 pgrep nginx,可能会匹配到 master 和 worker 进程
# 使用 -f 可以更精确地定位
pgrep -f "nginx -g"

4 -u (user) 选项:按用户查找

只查找指定用户运行的进程。

# 查找所有由 "root" 用户运行的 "nginx" 进程的 PID
pgrep -u root nginx
# 也可以指定多个用户,用逗号分隔
pgrep -u root,nginx nginx

5 -U (real user) 选项:按实际用户查找

-u 匹配的是有效用户ID (Effective User ID),而 -U 匹配的是实际用户ID (Real User ID),在大多数情况下两者相同,但在 sudo 等场景下会有区别。

# 查找所有实际用户为 "www-data" 的进程
pgrep -U www-data

6 -g (group) 选项:按用户组查找

匹配属于指定用户组的进程。

# 查找所有属于 "docker" 用户组的进程
pgrep -g docker

7 -P (Parent) 选项:查找指定父进程的子进程

查找某个父进程 ID 的所有子进程。

# 首先查找一个父进程的 PID,systemd
pgrep systemd
# 假设返回 PID 是 1
# 然后查找 PID 为 1 的所有子进程
pgrep -P 1

8 -o (oldest) 和 -n (newest) 选项:选择最旧或最新的进程

当有多个匹配的进程时,可以使用这两个选项来选择其中一个。

# 查找名为 "bash" 的最旧的进程的 PID
pgrep -o bash
# 查找名为 "bash" 的最新的进程的 PID
pgrep -n bash

9 -x (exact) 选项:精确匹配

默认情况下,pgrep 的匹配是“子字符串”匹配(即 nginx 会匹配 nginxnginx-worker)。-x 选项要求精确匹配整个进程名。

# 只会精确匹配名为 "nginx" 的进程,不会匹配 "nginx-worker"
pgrep -x nginx

10 -a (all) 选项:显示完整命令行

这个选项非常有用,它会输出完整的进程信息,包括 PID、PPID(父进程ID)、进程名和完整的命令行,其格式类似于 ps -eo pid,ppid,cmd

# 显示所有名为 "sshd" 的进程的详细信息
pgrep -a sshd

示例输出:

1234 1 /usr/sbin/sshd -D
5678 1234 /usr/sbin/sshd -D

pgreppkill 的关系

pgrep 有一个姊妹命令叫做 pkill

  • pgrepProcess Grep,只负责查找并打印出匹配的进程 ID。
  • pkillProcess Kill,查找匹配的进程,并向它们发送信号(默认是 SIGTERM,即终止进程)。

pkill 的选项和 pgrep 几乎完全一样,只是它的最终目的是“杀死”进程,而不是“打印”进程 ID。

示例:使用 pkill

# 向所有名为 "bad_process" 的进程发送 SIGTERM 信号,优雅地终止它们
pkill bad_process
# 向所有名为 "naughty_app" 的进程发送 SIGKILL 信号,强制杀死它们
pkill -9 naughty_app
# 或者使用信号名
pkill -KILL naughty_app

pgrep 在脚本中的应用

pgrep 的真正威力在于脚本中,因为它可以方便地将 PID 赋值给变量,用于后续操作。

示例脚本:检查并重启 Nginx 服务

#!/bin/bash
SERVICE="nginx"
# 使用 pgrep 检查服务是否正在运行
# pgrep 没有找到进程,它的退出状态码为非零
if pgrep "$SERVICE" > /dev/null; then
  echo "$SERVICE 服务正在运行 (PID: $(pgrep $SERVICE))。"
  # 可以在这里添加重启服务的逻辑
else
  echo "$SERVICE 服务没有运行。"
  # 启动服务
  systemctl start "$SERVICE"
  echo "$SERVICE 服务已启动。"
fi

在这个脚本中:

  • pgrep "$SERVICE" > /dev/null:将 pgrep 的输出(PID列表)重定向到 /dev/null,因为我们只关心它是否能找到进程(即退出状态码),而不需要看到 PID 本身。
  • if pgrep ...if 语句会检查命令的退出状态码,如果找到进程,pgrep 退出状态码为 0 (真),if 条件成立;否则为非零 (假),if 条件不成立。

命令 作用 优点 典型用例
ps aux \| grep pattern 查找进程并打印信息 功能强大,可定制性高 交互式查看复杂的进程状态
pgrep pattern 仅查找并输出匹配进程的 PID 简洁、高效、可靠,专为脚本设计 在脚本中获取 PID、检查进程是否存在
pkill pattern 查找进程并向其发送信号 快速批量管理进程 终止、挂起或唤醒一组进程

掌握 pgreppkill 可以让你在 Linux 系统管理和自动化脚本编写中如虎添翼,极大地提高工作效率。

分享:
扫描分享到社交APP
上一篇
下一篇