基于模式的 Linux 进程终止

LinuxLinuxBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

在 Linux 系统中,有效管理进程对于维持系统的稳定性和性能至关重要。虽然 kill 命令允许使用特定的进程 ID(PID)来终止进程,但在某些情况下,你需要根据模式来终止多个进程。这时,pkill 命令就显得非常有用。

本实验重点介绍如何使用 pkill 命令根据进程的名称、参数或其他条件来终止进程。你将学习如何识别正在运行的进程,使用模式匹配有选择地终止它们,并验证操作结果。这些技能对于 Linux 环境中的系统管理和故障排除至关重要。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL linux(("Linux")) -.-> linux/BasicFileOperationsGroup(["Basic File Operations"]) linux(("Linux")) -.-> linux/TextProcessingGroup(["Text Processing"]) linux(("Linux")) -.-> linux/ProcessManagementandControlGroup(["Process Management and Control"]) linux(("Linux")) -.-> linux/SystemInformationandMonitoringGroup(["System Information and Monitoring"]) linux/BasicFileOperationsGroup -.-> linux/chmod("Permission Modifying") linux/TextProcessingGroup -.-> linux/grep("Pattern Searching") linux/ProcessManagementandControlGroup -.-> linux/pkill("Pattern-Based Killing") linux/SystemInformationandMonitoringGroup -.-> linux/ps("Process Displaying") subgraph Lab Skills linux/chmod -.-> lab-271359{{"基于模式的 Linux 进程终止"}} linux/grep -.-> lab-271359{{"基于模式的 Linux 进程终止"}} linux/pkill -.-> lab-271359{{"基于模式的 Linux 进程终止"}} linux/ps -.-> lab-271359{{"基于模式的 Linux 进程终止"}} end

理解进程管理和基本进程终止

在第一步中,我们将探讨如何识别正在运行的进程,并使用基本的模式匹配来终止它们。Linux 提供了多个用于进程管理的命令,包括 pspgreppkill

创建测试进程

让我们先创建一个简单的脚本,并将其作为后台进程运行。我们将创建该脚本的多个实例,以模拟你需要终止多个相似进程的场景。

首先,导航到项目目录并创建一个名为 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 命令来终止脚本的所有实例:

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 &

现在,让我们尝试向进程发送不同的信号:

  1. 发送 SIGHUP 信号(信号 1):
pkill -HUP -f signal_handler.sh
  1. 再次启动脚本并发送 SIGINT 信号(信号 2):
~/project/signal_handler.sh &
pkill -INT -f signal_handler.sh
  1. 再次启动脚本并发送默认的 SIGTERM 信号(信号 15):
~/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 的操作

你还可以将 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 命令来管理进程。这个强大的命令允许你根据各种条件终止进程,使其成为系统管理的重要工具。

涵盖的关键概念:

  1. 基本进程终止:你学习了如何使用 ps 命令识别正在运行的进程,并使用 pkill 结合基本的模式匹配来终止它们。

  2. 选择性进程终止:你探索了如何使用模式匹配,根据进程的命令行参数有选择地针对特定进程,从而精确控制要终止的进程。

  3. 高级进程终止选项:你发现了 pkill 的高级选项,包括如何:

    • 向进程发送不同类型的信号
    • 根据进程的运行时长终止进程
    • pkill 的作用范围限制为特定用户拥有的进程

这些技能对于维护 Linux 环境中的系统稳定性、管理资源和进行故障排除非常有价值。通过掌握 pkill 命令,你为自己的 Linux 系统管理工具包增添了一个重要的工具。