在编程过程中,我经常需要杀死某个进程。 我现在的做法是:
[~]$ ps aux | grep 'python csp_build.py'
user 5124 1.0 0.3 214588 13852 pts/4 Sl+ 11:19 0:00 python csp_build.py
user 5373 0.0 0.0 8096 960 pts/6 S+ 11:20 0:00 grep python csp_build.py
[~]$ kill 5124
如何自动提取进程 id 并在同一行命令中终止它?类似这样:
[~]$ ps aux | grep 'python csp_build.py' | kill <regex that returns the pid>
在 bash 中,仅使用你问题中列出的基本工具,你可以这样做:
kill $(ps aux | grep '[p]ython csp_build.py' | awk '{print $2}')
以 sleep
命令作为测试示例,下面是它的运行记录 :
命令详解如下:
ps aux
: 这是 Unix/Linux 中的 ps
命令的一个变体,用于显示系统中所有用户的进程状态。aux
参数组合使 ps
输出了详细的进程列表,包括用户、PID、CPU 和内存使用情况等信息。grep '[s]leep'
: 使用 grep
命令搜索上述进程列表,查找含有“sleep”的行。这里的正则表达式 [s]leep
中的方括号表示匹配字符 s
。当你执行 sleep 3600 &
然后紧接着运行 ps -ef | grep sleep
时,你会看到有两个包含 "sleep" 的进程,一个是 sleep 3600
,另一个是 grep sleep
(因为它们两者都包含了 "sleep")。然而,执行 ps -ef | grep '[s]leep'
时,不会生成一个包含 "sleep" 关键词的 grep
进程,而是生成一个命令为 grep '[s]leep'
的进程。关键在于:grep
正在查找正则表达式匹配项,即任何包含字符 "s" 且后面紧跟着 "leep" 的文本。换句话说,它在查找 "sleep",但是该 grep
进程本身的命令是 grep '[s]leep'
,其中并没有包含关键词 "sleep",因此 grep
不会匹配到进程自身。awk '{print $2}'
: awk
是一个强大的文本处理工具,这里它被用于处理 grep
筛选出的每一行文本。'{print $2}'
命令让 awk
打印每行的第二个字段(以空格分隔),这个字段通常是进程的 PID (进程标识符)。$(...)
: 这是命令替换语法,shell 会在执行主命令之前先执行括号内的命令,并将结果作为参数传给外面的命令。也就是说,这里将 ps aux | grep '[s]leep' | awk '{print $2}'
的输出(即所有 sleep
进程的 PID)作为参数传递给括号外的命令。kill
: 最终命令是 kill
,它接收之前命令替换得出的 PID 列表,然后向每个 PID 发送一个默认的终止信号(通常是 SIGTERM 信号),尝试停止这些进程。综上所述,整个命令的目的是查找所有名为 sleep
的进程,并逐个发送终止信号以关闭它们。
这种方法比添加 | grep -v grep
来排除 grep 进程要少用一个 grep
进程,既优雅又巧妙。
另外,如果你不局限于使用上述基本工具,有一个方便的 pgrep
命令,它可以基于特定条件来查找进程。
例如,你可以使用 pgrep sleep
来输出所有 sleep
命令的进程 ID (默认情况下,它会匹配进程名称)。如果你想匹配 ps
显示的完整命令行,可以使用类似 pgrep -f 'sleep 3600'
的命令。
一旦你确定它只会显示你关注的进程,接下来就可以使用相同的参数配合 pkill
命令向所有这些进程发送终止信号。
这里 pgrep sleep
只是为了验证,实际只需执行 pkill sleep
一行命令。
参考: