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

pgrep 就像是 ps 和 grep 的结合体,但它更简洁、更强大。
为什么需要 pgrep?
在 pgrep 出现之前,我们通常使用 ps 和 grep 的组合来查找进程 ID,
# 查找名为 "nginx" 的所有进程的 PID
ps aux | grep nginx | grep -v grep | awk '{print $2}'
这条命令虽然能工作,但存在几个问题:
- 冗长:需要组合多个命令 (
ps,grep,awk)。 - 脆弱:如果进程名中包含 "grep",或者
ps的输出格式发生变化(比如不同发行版的ps默认格式不同),命令就会出错或失效。 - 效率低:需要生成整个进程列表,然后通过管道传递给
grep进行过滤。
pgrep 正是为了解决这些问题而生,它直接与内核通信,只返回匹配的 PID,更加高效和可靠。

pgrep 的基本语法
pgrep [选项] 模式
模式:通常是进程的名称,也可以是其他属性。[选项]:用于控制匹配规则和输出格式。
常用选项和示例
1 基本用法:按进程名查找
这是 pgrep 最常见的用法。
# 查找所有名为 "sshd" 的进程的 PID pgrep sshd
如果找到多个匹配的进程,pgrep 会默认将它们的 PID 以空格分隔打印在一行上。
示例输出:
1234 5678 9012
2 -l (list names) 选项:显示进程名
在输出 PID 的同时,也显示进程名。

# 查找 "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 会匹配 nginx 和 nginx-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
pgrep 与 pkill 的关系
pgrep 有一个姊妹命令叫做 pkill。
pgrep:Process Grep,只负责查找并打印出匹配的进程 ID。pkill:Process 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 |
查找进程并向其发送信号 | 快速批量管理进程 | 终止、挂起或唤醒一组进程 |
掌握 pgrep 和 pkill 可以让你在 Linux 系统管理和自动化脚本编写中如虎添翼,极大地提高工作效率。
