简介
在 Linux 系统中,有效管理进程对于维持系统的稳定性和性能至关重要。虽然 kill
命令允许使用特定的进程 ID(PID)来终止进程,但在某些情况下,你需要根据模式来终止多个进程。这时,pkill
命令就显得非常有用。
本实验重点介绍如何使用 pkill
命令根据进程的名称、参数或其他条件来终止进程。你将学习如何识别正在运行的进程,使用模式匹配有选择地终止它们,并验证操作结果。这些技能对于 Linux 环境中的系统管理和故障排除至关重要。
在 Linux 系统中,有效管理进程对于维持系统的稳定性和性能至关重要。虽然 kill
命令允许使用特定的进程 ID(PID)来终止进程,但在某些情况下,你需要根据模式来终止多个进程。这时,pkill
命令就显得非常有用。
本实验重点介绍如何使用 pkill
命令根据进程的名称、参数或其他条件来终止进程。你将学习如何识别正在运行的进程,使用模式匹配有选择地终止它们,并验证操作结果。这些技能对于 Linux 环境中的系统管理和故障排除至关重要。
在第一步中,我们将探讨如何识别正在运行的进程,并使用基本的模式匹配来终止它们。Linux 提供了多个用于进程管理的命令,包括 ps
、pgrep
和 pkill
。
让我们先创建一个简单的脚本,并将其作为后台进程运行。我们将创建该脚本的多个实例,以模拟你需要终止多个相似进程的场景。
首先,导航到项目目录并创建一个名为 rogue_app.sh
的脚本:
cd ~/project
nano rogue_app.sh
在脚本中添加以下内容:
#!/bin/bash
while true; do
echo "Process running with PID $$"
sleep 5
done
这个脚本会运行一个无限循环,每 5 秒打印一次它的进程 ID(PID)。
现在,让脚本可执行:
chmod +x ~/project/rogue_app.sh
让我们在后台运行该脚本的多个实例:
for i in {1..5}; do
~/project/rogue_app.sh &
done
命令末尾的 &
符号会将每个脚本实例作为后台进程运行,这样你就可以继续使用终端。
要查看你刚刚启动的进程,请使用带有适当选项的 ps
命令:
ps aux | grep rogue_app.sh
输出将类似于以下内容:
labex 12345 0.0 0.0 2308 580 pts/0 S 10:00 0:00 /bin/bash /home/labex/project/rogue_app.sh
labex 12346 0.0 0.0 2308 580 pts/0 S 10:00 0:00 /bin/bash /home/labex/project/rogue_app.sh
labex 12347 0.0 0.0 2308 580 pts/0 S 10:00 0:00 /bin/bash /home/labex/project/rogue_app.sh
labex 12348 0.0 0.0 2308 580 pts/0 S 10:00 0:00 /bin/bash /home/labex/project/rogue_app.sh
labex 12349 0.0 0.0 2308 580 pts/0 S 10:00 0:00 /bin/bash /home/labex/project/rogue_app.sh
labex 12350 0.0 0.0 2432 584 pts/0 S+ 10:00 0:00 grep --color=auto rogue_app.sh
请注意,实际的 PID(第二列中的数字)在你的系统上会有所不同。
现在,让我们使用 pkill
命令来终止脚本的所有实例:
pkill -f rogue_app.sh
-f
选项告诉 pkill
要匹配完整的命令行,而不仅仅是进程名。这很重要,因为脚本运行时,进程名通常是解释器(如 /bin/bash
),而不是脚本名。
验证脚本的所有实例是否已被终止:
ps aux | grep rogue_app.sh
现在,你应该只会在输出中看到 grep
命令本身:
labex 12351 0.0 0.0 2432 584 pts/0 S+ 10:01 0:00 grep --color=auto rogue_app.sh
这证实了 rogue_app.sh
的所有实例都已成功终止。
在实际场景中,你通常需要更有选择性地终止进程。pkill
命令允许你使用模式匹配,根据各种条件来针对特定的进程。
让我们创建一个新的脚本,并使用不同的命令行参数来运行它:
cd ~/project
nano service_worker.sh
在脚本中添加以下内容:
#!/bin/bash
while true; do
echo "Running service worker with argument: $1"
sleep 5
done
使脚本可执行:
chmod +x ~/project/service_worker.sh
现在,让我们使用不同的参数运行该脚本的多个实例:
~/project/service_worker.sh normal &
~/project/service_worker.sh normal &
~/project/service_worker.sh --malfunctioning &
~/project/service_worker.sh --malfunctioning &
~/project/service_worker.sh emergency &
这将创建五个后台进程:两个“正常”工作进程、两个“故障”工作进程和一个“紧急”工作进程。
检查正在运行的进程:
ps aux | grep service_worker.sh
你应该会看到类似于以下的输出:
labex 12360 0.0 0.0 2308 580 pts/0 S 10:05 0:00 /bin/bash /home/labex/project/service_worker.sh normal
labex 12361 0.0 0.0 2308 580 pts/0 S 10:05 0:00 /bin/bash /home/labex/project/service_worker.sh normal
labex 12362 0.0 0.0 2308 580 pts/0 S 10:05 0:00 /bin/bash /home/labex/project/service_worker.sh --malfunctioning
labex 12363 0.0 0.0 2308 580 pts/0 S 10:05 0:00 /bin/bash /home/labex/project/service_worker.sh --malfunctioning
labex 12364 0.0 0.0 2308 580 pts/0 S 10:05 0:00 /bin/bash /home/labex/project/service_worker.sh emergency
labex 12365 0.0 0.0 2432 584 pts/0 S+ 10:05 0:00 grep --color=auto service_worker.sh
现在,让我们有选择地仅终止带有 --malfunctioning
参数的进程:
pkill -f "service_worker.sh --malfunctioning"
-f
选项确保 pkill
匹配完整的命令行,包括参数。
验证是否只有目标进程被终止:
ps aux | grep service_worker.sh
现在你应该只会看到“正常”和“紧急”进程:
labex 12360 0.0 0.0 2308 580 pts/0 S 10:05 0:00 /bin/bash /home/labex/project/service_worker.sh normal
labex 12361 0.0 0.0 2308 580 pts/0 S 10:05 0:00 /bin/bash /home/labex/project/service_worker.sh normal
labex 12364 0.0 0.0 2308 580 pts/0 S 10:05 0:00 /bin/bash /home/labex/project/service_worker.sh emergency
labex 12366 0.0 0.0 2432 584 pts/0 S+ 10:06 0:00 grep --color=auto service_worker.sh
这展示了你如何根据命令行中的特定模式有选择地终止进程。
现在,让我们终止所有剩余的服务工作进程:
pkill -f service_worker.sh
验证所有服务工作进程是否已被终止:
ps aux | grep service_worker.sh
现在你应该只会看到 grep
命令本身:
labex 12367 0.0 0.0 2432 584 pts/0 S+ 10:07 0:00 grep --color=auto service_worker.sh
在这一步中,我们将探索 pkill
命令的一些高级选项,这些选项可实现更复杂的进程管理。
默认情况下,pkill
会向进程发送 SIGTERM 信号(信号 15)。这个信号允许进程优雅地终止,关闭文件并执行清理操作。不过,在某些情况下,你可能想使用不同的信号。
让我们创建一个处理信号的脚本:
cd ~/project
nano signal_handler.sh
在脚本中添加以下内容:
#!/bin/bash
trap 'echo "Received SIGHUP (1)"; exit 0' SIGHUP
trap 'echo "Received SIGINT (2)"; exit 0' SIGINT
trap 'echo "Received SIGTERM (15)"; exit 0' SIGTERM
echo "Process started with PID $$"
echo "Use: pkill -[signal] -f signal_handler.sh to send signals"
while true; do
sleep 1
done
使脚本可执行:
chmod +x ~/project/signal_handler.sh
在后台运行脚本:
~/project/signal_handler.sh &
现在,让我们尝试向进程发送不同的信号:
pkill -HUP -f signal_handler.sh
~/project/signal_handler.sh &
pkill -INT -f signal_handler.sh
~/project/signal_handler.sh &
pkill -f signal_handler.sh ## Default is SIGTERM
对于每个信号,你应该会在进程退出前在终端输出中看到相应的消息。
pkill
允许你使用 --newer
和 --older
选项根据进程的运行时长来针对特定进程。
让我们创建几个不同启动时间的进程:
cd ~/project
nano age_test.sh
在脚本中添加以下内容:
#!/bin/bash
while true; do
echo "Process running with PID $$"
sleep 5
done
使脚本可执行:
chmod +x ~/project/age_test.sh
启动第一个进程并记录参考文件:
~/project/age_test.sh &
touch ~/project/reference_time
等待几秒钟,然后再启动两个进程:
sleep 5
~/project/age_test.sh &
~/project/age_test.sh &
现在,让我们只终止在参考文件创建之后启动的进程:
pkill -f --newer ~/project/reference_time age_test.sh
验证哪些进程仍在运行:
ps aux | grep age_test.sh
你应该会看到只有第一个进程仍在运行,因为它是在参考文件创建之前启动的。
终止剩余的进程:
pkill -f age_test.sh
你还可以将 pkill
的操作限制为特定用户拥有的进程。在多用户系统中,这特别有用。
为了演示,让我们以当前用户的身份运行几个进程:
~/project/rogue_app.sh &
~/project/rogue_app.sh &
现在,让我们终止这些进程,但只终止当前用户拥有的进程:
pkill -f -u $(whoami) rogue_app.sh
-u
选项指定进程所有者的用户名。$(whoami)
命令替换会获取你当前的用户名。
验证所有进程是否已被终止:
ps aux | grep rogue_app.sh
你应该只会在输出中看到 grep
命令本身。
这种按所有者针对进程的能力在多用户环境中特别有用,因为你可以避免影响其他用户的进程。
在这个实验中,你学习了如何在 Linux 环境中使用 pkill
命令来管理进程。这个强大的命令允许你根据各种条件终止进程,使其成为系统管理的重要工具。
涵盖的关键概念:
基本进程终止:你学习了如何使用 ps
命令识别正在运行的进程,并使用 pkill
结合基本的模式匹配来终止它们。
选择性进程终止:你探索了如何使用模式匹配,根据进程的命令行参数有选择地针对特定进程,从而精确控制要终止的进程。
高级进程终止选项:你发现了 pkill
的高级选项,包括如何:
pkill
的作用范围限制为特定用户拥有的进程这些技能对于维护 Linux 环境中的系统稳定性、管理资源和进行故障排除非常有价值。通过掌握 pkill
命令,你为自己的 Linux 系统管理工具包增添了一个重要的工具。