ChatGPT解决这个技术问题 Extra ChatGPT

使用 bash 和正则表达式在一行中查找并终止进程

我经常需要在编程过程中杀死一个进程。

我现在的做法是:

[~]$ 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>
相信我! :'D 您选择的第一个答案比您在答案中告诉您的解决方案复杂得多。我宁愿选择你的方式。
检查进程是否存在的最佳方法:stackoverflow.com/questions/3043978/…

K
Kerem Baydoğan

bash 中,您应该能够:

kill $(ps aux | grep '[p]ython csp_build.py' | awk '{print $2}')

其运作详情如下:

ps 为您提供所有进程的列表。

基于您的搜索字符串的 grep 过滤器 [p] 是阻止您获取实际 grep 进程本身的技巧。

awk 只为您提供每行的第二个字段,即 PID。

$(x) 构造意味着执行 x 然后获取其输出并将其放在命令行上。上面构造中的 ps 管道的输出是进程 ID 列表,因此您最终会得到类似 kill 1234 1122 7654 的命令。

这是一个显示它在行动的成绩单:

pax> sleep 3600 &
[1] 2225
pax> sleep 3600 &
[2] 2226
pax> sleep 3600 &
[3] 2227
pax> sleep 3600 &
[4] 2228
pax> sleep 3600 &
[5] 2229
pax> kill $(ps aux | grep '[s]leep' | awk '{print $2}')
[5]+  Terminated              sleep 3600
[1]   Terminated              sleep 3600
[2]   Terminated              sleep 3600
[3]-  Terminated              sleep 3600
[4]+  Terminated              sleep 3600

你可以看到它终止了所有的睡眠者。

更详细地解释 grep '[p]ython csp_build.py' 位:

当您执行 sleep 3600 & 后跟 ps -ef | grep sleep 时,您往往会得到 两个 包含 sleep 的进程,即 sleep 3600grep sleep(因为它们都包含 sleep他们,那不是火箭科学)。

但是,ps -ef | grep '[s]leep' 不会创建包含 sleep 的进程,而是创建 grep '[s]leep',这是一个棘手的问题:grep 找不到它,因为它正在寻找正则表达式“来自字符类 [s](即 s)后跟 leep

换句话说,它正在寻找 sleep,但 grep 进程是 grep '[s]leep',其中没有 sleep

当我看到这个(这里的某人)时,我立即开始使用它,因为

比添加少一个过程 | grep -v grep;和

它优雅而狡猾,是一种罕见的组合:-)


P
Phrogz

如果你有 pkill,

pkill -f csp_build.py

如果您只想对进程名称(而不是完整的参数列表)进行 grep,则不要使用 -f


a
a20

一个班轮:

ps aux | grep -i csp_build | awk '{print $2}' | xargs sudo kill -9

打印出第 2 列: awk '{print $2}'

sudo 是可选的

运行 kill -9 5124、kill -9 5373 等(kill -15 更优雅但稍慢)

奖金:

我还在我的 .bash_profile 中定义了 2 个快捷方式函数(~/.bash_profile 用于 osx,您必须查看适用于您的 *nix 机器的方法)。

p 关键字列出了所有包含关键字用法的进程,例如: p csp_build 、 p python 等

bash_profile 代码:

# FIND PROCESS
function p(){
        ps aux | grep -i $1 | grep -v grep
}

ka 关键字杀死所有使用此关键字的进程,例如:ka csp_build、ka python 等可选的杀死级别,例如:ka csp_build 15、ka python 9

bash_profile 代码:

# KILL ALL
function ka(){

    cnt=$( p $1 | wc -l)  # total count of processes found
    klevel=${2:-15}       # kill level, defaults to 15 if argument 2 is empty

    echo -e "\nSearching for '$1' -- Found" $cnt "Running Processes .. "
    p $1

    echo -e '\nTerminating' $cnt 'processes .. '

    ps aux  |  grep -i $1 |  grep -v grep   | awk '{print $2}' | xargs sudo kill -klevel
    echo -e "Done!\n"

    echo "Running search again:"
    p "$1"
    echo -e "\n"
}

N
Nazik
killall -r regexp

-r, --regexp

将进程名称模式解释为扩展的正则表达式。


R
Rakib Fiha

这将只返回 pid

pgrep -f 'process_name'

所以要在一行中杀死任何进程:

kill -9 $(pgrep -f 'process_name')

或者,如果您知道进程的确切名称,您也可以尝试 pidof:

kill -9 $(pidof 'process_name')

但是,如果您不知道进程的确切名称,pgrep 会更好。

如果有多个进程以相同的名称运行,并且您想杀死第一个进程,那么:

kill -9 $(pgrep -f 'process_name' | head -1)

还要注意的是,如果您担心区分大小写,那么您可以像在 grep 中一样添加 -i 选项。例如:

kill -9 $(pgrep -fi chrome)

man 7 signalman signalman pgrep 上有关信号和 pgrep 的更多信息


S
Sergey Kishenin

尝试使用

ps aux | grep 'python csp_build.py' | head -1 | cut -d " " -f 2 | xargs kill

不得不稍微改变一下。这行得通。谢谢。 :) ps辅助| grep 'python csp_build.py' |头-1 |剪切 -d " " -f 5 | xargs 杀死
ps aux | grep 'python csp_build.py' | awk '{print $2}' | xargs kill 为我工作。谢谢
请记住,孩子们,Awk 可以做 grep 可以做的所有事情,而且大部分都简单而优雅。 grep x y | awk '{ z }' 的普通情况总是写成 awk '/x/ { z }' y 更好——另见 useless use of grep
N
NGix

您只能将 pkill '^python*' 用于正则表达式进程终止。

如果您想在杀死之前查看要杀死或找到的内容,只需使用 pgrep -l '^python*' 其中 -l 还输出进程名称。如果您不想使用 pkill,只需使用:

pgrep '^python*' | xargs kill


v
vr286

使用 pgrep - 在许多平台上可用:

kill -9 `pgrep -f cps_build`

pgrep -f 将返回所有符合“cps_build”的PID


如果您有 pgrep,那么您也将有 pkill。与往常一样,don't use kill -9 除非您知道为什么 kill -15(默认值)或 kill -2 不起作用。
这看起来像是对 @nathanael's answer 的更糟糕的解释,它省略了误导的 -9 并使用了正确的现代命令替换语法。相反,赞成;当然,pkill answer 更好。
@tripleee 在这种情况下, kill -9 正是我想要的 - 以极端偏见终止所有罪犯。此外,我已经使用 kill -9 多年,没有任何问题。在我看来,总会有一个纯粹主义者阵营和一个完成事情的现实主义者阵营,我属于后者(在这件事上)。
你错过了“除非你知道为什么”部分吗?我完全赞成把事情做好,但在您理解 -9 的实际含义之前,这是一种常见的自取其辱的方法。
@tripleee 嘿,tripleee,我最近发现你是对的,kill -15 是一个更好的选择,因为它让应用程序有机会优雅地杀死自己。我已经相应地更改了我的代码:stackoverflow.com/a/30486159/163382
a
avivamg

解决方案是过滤具有精确模式的进程,解析 pid,并构造一个参数列表来执行终止进程:

ps -ef  | grep -e <serviceNameA> -e <serviceNameB> -e <serviceNameC> |
awk '{print $2}' | xargs sudo kill -9

文档说明:

ps 实用程序显示一个标题行,然后是包含有关具有控制终端的所有进程的信息的行。

-e 显示有关其他用户进程的信息,包括那些

-f 显示 uid、pid、父 pid、最近的 CPU 使用率、进程启动

grep 实用程序搜索任何给定的输入文件,选择符合 -e 模式的行,--regexp=pattern 指定在搜索输入期间使用的模式:如果输入行匹配任何指定的模式,则选择该输入行。当使用多个 -e 选项指定多个模式时,或者当模式以破折号 (`-') 开头时,此选项最有用。

xargs - 构造参数列表并执行实用程序

kill - 终止或通知进程

号信号 - KILL(不可捕获,不可忽略的杀戮)

例子:

ps -ef  | grep -e node -e loggerUploadService.sh -e applicationService.js |
awk '{print $2}' | xargs sudo kill -9

这是一个优越(不太复杂)的答案和很好的描述/解释......
A
Alexander Kjäll

你可以用 awk 和 backtics 来做

ps auxf |grep 'python csp_build.py'|`awk '{ print "kill " $2 }'`

awk 中的 $2 打印第 2 列,并且 backtics 运行打印的语句。

但是一个更干净的解决方案是让 python 进程将它的进程 ID 存储在 /var/run 中,然后你可以简单地读取该文件并杀死它。


那么你不会杀死进程 5124 和 5373 吗?我想这不是问题。
这应该不是问题,但是您始终可以添加另一个 grep 以排除 grep 进程:grep 和 awk 之间的“grep -v grep”
使用稍微修改的命令进行了测试。但它并没有杀死进程,只打印了 kill 。 ps辅助| grep '[p]ython csp_build.py' | awk '{print "kill " $2}'
只需要将打印“kill”$2 语句与系统(“kill”$2)交换。然后它工作。 :)
S
Serge

我的任务是杀死与放置在特定目录中的正则表达式匹配的所有内容(在硒测试之后,并非所有内容都停止了)。这对我有用:

for i in `ps aux | egrep "firefox|chrome|selenium|opera"|grep "/home/dir1/dir2"|awk '{print $2}'|uniq`; do kill $i; done

kill-9 选项可能过于激进。它不允许他们释放资源。
好的!唯一一个考虑到可能有多个匹配过程的事实!一个小提示:也许您可能想在管道中添加“grep -v grep”或类似的东西,以确保 grep 进程本身不会出现在您的进程列表中。
kill 接受多个进程,因此循环基本上没用;如本页其他地方所述,您不应使用 kill -9,除非您知道该进程不会仅响应 kill
删除 -9 没什么大不了的,为什么要投反对票。你最好编辑答案。
a
a20

通过关键字 midori 杀死进程,例如:

kill -SIGTERM $(pgrep -i midori)


V
Vijay
ps -o uid,pid,cmd|awk '{if($1=="username" && $3=="your command") print $2}'|xargs kill -15

由于每日限制无法 +1,但使用 ps-o 选项值得使用。
ps不要给我太多。 [~]$ ps PID TTY TIME CMD 6365 pts/6 00:00:00 ps 29112 pts/6 00:00:00 bash
s
schot

仅使用 awk(和 ps)的方法:

ps aux | awk '$11" "$12 == "python csp_build.py" { system("kill " $2) }'

通过使用字符串相等测试,我防止匹配此过程本身。


出于某种原因,我没有在“python csp_build.py”上获得成功。但是只有“python”才能成功。
R
Robert1968

给 -f 给 pkill

pkill -f /usr/local/bin/fritzcap.py

.py 文件的确切路径是

# ps ax | grep fritzcap.py
 3076 pts/1    Sl     0:00 python -u /usr/local/bin/fritzcap.py -c -d -m

N
Neil Gatenby

这里有很多好的答案 - 我使用了 OP 接受的答案。只需添加一个关于 pkillpgrep 的小警告说明。正如您从 their manual pages 中看到的,在您的操作系统上,某些操作系统的进程名称有 15 个字符的限制。 -f 选项在我的操作系统上解决了这个问题,但在找到该选项之前我遇到了麻烦!


sudo pkill -f 'pattern' 为我工作。
N
Nathanael

我开始使用这样的东西:

kill $(pgrep 'python csp_build.py')

A
Alex V

您不需要 ps 的用户开关。

kill `ps ax | grep 'python csp_build.py' | awk '{print $1}'`

k
kashu.org

在某些情况下,我想像这样同时杀死进程:

➜  ~  sleep 1000 &
[1] 25410
➜  ~  sleep 1000 &
[2] 25415
➜  ~  sleep 1000 &
[3] 25421
➜  ~  pidof sleep
25421 25415 25410
➜  ~  kill `pidof sleep`
[2]  - 25415 terminated  sleep 1000                                                             
[1]  - 25410 terminated  sleep 1000
[3]  + 25421 terminated  sleep 1000

但是,我认为这在你的情况下有点不合适。(可能在后台运行 python a,python b,python x...。)


y
yosemite_k

如果 pkill -f csp_build.py 没有终止进程,您可以添加 -9 以发送不会被忽略的终止信号。即pkill -9 -f csp_build.py


F
F. Hauri - Give Up GitHub

使用 ps 命令的 -C 标志

-C cmdlist 按命令名选择。这将选择其可执行名称在 cmdlist 中给出的进程。

第一种情况,简单的命令

因此,如果您通过标准 shebang 运行脚本并以他的名字调用它们:

/path/to/csp_build.py

你可能会发现他们

ps -C csp_build.py

所以

kill $(ps -C csp_build.py ho pid)

可能就够了。

第二种情况,搜索 cmd

更强一点,但仍然比这个 SO 问题中的大多数其他答案要快得多......

如果你不知道这是运行的,或者如果你运行它们

python csp_build.py
python3 csp_build.py
python /path/to/csp_build.py

您可以通过运行找到它们:

ps -C python,python3,csp_build.py who pid,cmd | grep csp_build.py

然后使用 sed

kill $(ps -C python,python3,csp_build.py who pid,cmd |
    sed -ne '/csp_build.py/s/^ *\([0-9]\+\) .*$/\1/p')

J
Juan Diego Godoy Robles

从一个常见的 PPID 开始杀死我们自己的进程非常频繁,与 –P 标志相关联的 pkill 对我来说是赢家。使用@ghostdog74 示例:

# sleep 30 &                                                                                                      
[1] 68849
# sleep 30 &
[2] 68879
# sleep 30 &
[3] 68897
# sleep 30 &
[4] 68900
# pkill -P $$                                                                                                         
[1]   Terminated              sleep 30
[2]   Terminated              sleep 30
[3]-  Terminated              sleep 30
[4]+  Terminated              sleep 30

我什至不知道你在这里想做什么。更多的文字,也许它会有意义。
m
mrhassell

当 Firefox 被脚本抨击和 CPU 抨击时,我用它来杀死 Firefox :) 用你想死的应用程序替换“Firefox”。我在 Bash shell - OS X 10.9.3 Darwin 上。

kill -Hup $(ps ux | grep Firefox | awk 'NR == 1 {next} {print $2}' | uniq | sort)


grep Firefox | awk 'NR == 1 { next } ...'替换为awk 'NR == 1 || $11 !~ /Firefox/ { next } ...',不仅可以节省流程,还可以提高精度。在纯 Awk 中摆脱 sort | uniq 也不难(当然 uniq | sort 是错误的——它会错过任何不相邻的重复项,并通过对 输出进行不必要的排序来隐藏错误uniq)。
K
Kostyantyn

我使用 gkill processname,其中 gkill 是以下脚本:

cnt=`ps aux|grep $1| grep -v "grep" -c`
if [ "$cnt" -gt 0 ]
then
    echo "Found $cnt processes - killing them"
    ps aux|grep $1| grep -v "grep"| awk '{print $2}'| xargs kill
else
    echo "No processes found"
fi

注意:它不会杀死命令行中包含“grep”的进程。


像牦牛棚的许多其他改造一样,这充满了 useless use of grep 和其他常见的 shell 脚本反模式。
r
rashok

在 bash 中的一行中查找并杀死所有进程。

kill -9 $(ps -ef | grep '<exe_name>' | grep -v 'grep' | awk {'print $2'})

ps -ef | grep '' - 提供与模式匹配的正在运行的进程详细信息(uname、pid 等)列表。输出列表包括这个 grep 命令也可以搜索它。现在为了杀死我们需要忽略这个 grep 命令进程。

ps -ef | grep '' | grep -v 'grep' - 使用 -v 'grep' 添加另一个 grep 会删除当前的 grep 进程。

然后使用 awk 单独获取进程 ID。

然后将此命令保留在 $(...) 中并将其传递给 kill 命令,以杀死所有进程。


M
Mark

基于 https://stackoverflow.com/a/3510879/15603477 答案。小优化。

ps aux | grep 'python csp_build.py' | head -1 | tr -s ' ' | cut -d " " -f 2 | xargs kill

通过使用 tr -s ' ' 将多个空格(如果有)压缩到 1 个空格。

如果您遇到Operation not permitted,请按照此>> https://unix.stackexchange.com/questions/89316/how-to-kill-a-process-that-says-operation-not-permitted-when-attempted


R
RARE Kpop Manifesto

如果您想大部分awk 内完成,请尝试

  for i in $(jot 5); do 
 (python3 -c 'import sys; [ print(_) for _ in sys.stdin ]' ) & done; 
  
  sleep 1; ps aux | {m,g}awk '

       /[p]ython/ { 
              _=(_)" "$2 
       } END { 
           system("echo \47 kill "(_)" \47")
           system(      "kill -9 " _) }'


[302] 14236
[303] 14237
[304] 14238
[305] 14239
[306] 14240
[303]  + suspended (tty input)  ( python3 -c 'import sys; [ print(_) for _ in sys.stdin ]'; )
[305]  + suspended (tty input)  ( python3 -c 'import sys; [ print(_) for _ in sys.stdin ]'; )
[304]  + suspended (tty input)  ( python3 -c 'import sys; [ print(_) for _ in sys.stdin ]'; )
[302]  + suspended (tty input)  ( python3 -c 'import sys; [ print(_) for _ in sys.stdin ]'; )
[306]  + suspended (tty input)  ( python3 -c 'import sys; [ print(_) for _ in sys.stdin ]'; )
 
 kill  14239 14237 14236 14240 14238 
 
[305]    killed     ( python3 -c 'import sys; [ print(_) for _ in sys.stdin ]'; )
[303]    killed     ( python3 -c 'import sys; [ print(_) for _ in sys.stdin ]'; )
[306]  + killed     ( python3 -c 'import sys; [ print(_) for _ in sys.stdin ]'; )
[304]  - killed     ( python3 -c 'import sys; [ print(_) for _ in sys.stdin ]'; )
[302]  + killed     ( python3 -c 'import sys; [ print(_) for _ in sys.stdin ]'; )

O
Oras

对于基本 bash 版本

杀死 $(pidof my_process)


A
Akshay Shah

以下命令将派上用场:

kill $(ps -elf | grep <process_regex>| awk {'print $4'})

例如,ps -elf | grep top

    0 T ubuntu    6558  6535  0  80   0 -  4001 signal 11:32 pts/1    00:00:00 top
    0 S ubuntu    6562  6535  0  80   0 -  2939 pipe_w 11:33 pts/1    00:00:00 grep --color=auto top

kill -$(ps -elf | grep top| awk {'print $4'})

    -bash: kill: (6572) - No such process
    [1]+  Killed                  top

如果进程仍然卡死,使用“-9”扩展hardkill,如下:

kill -9 $(ps -elf | grep top| awk {'print $4'})

希望对您有所帮助...!


A
Al Ro

我不喜欢纯粹根据 grep 的盲目结果来杀死东西——如果我错误地匹配了超出预期的内容怎么办?

我知道这会被命令行纯粹主义者否决,但我更喜欢这种情况下的交互式过滤器,例如pick(apt-get install pick)。使用这种工具,过滤后的结果会在您键入时显示,因此您可以准确地看到当您按 Enter 时会被杀死的内容。

因此,单线将成为

function killpick { ps ax | pick -q "$1" | awk  '{print $1}' | xargs kill -9; }

killpick 本身提供了一个带有增量过滤的选择器,可选参数为过滤器提供了一个起始字符串。