【问题标题】:Find and kill a process in one line using bash and regex使用 bash 和正则表达式在一行中查找并终止进程
【发布时间】:2011-03-31 10:54:00
【问题描述】:

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

我现在的做法是:

[~]$ 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/…

标签: regex bash terminal awk


【解决方案1】:

你可以用 awk 和 backtics 做到这一点

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

$2 in awk 打印第 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}'
  • 只需要将 print "kill " $2 语句与系统 ("kill " $2) 交换。然后它工作。 :)
【解决方案2】:

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

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

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

【讨论】:

  • 出于某种原因,我没有在“python csp_build.py”上获得成功。但是只有“python”才能成功。
【解决方案3】:

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 &amp; 后跟ps -ef | grep sleep 时,您往往会得到两个 包含sleep 的进程,sleep 3600grep sleep(因为它们都有@ 987654339@ 在其中,这不是火箭科学)。

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

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

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

  • 比添加| grep -v grep少一个过程;和
  • 它优雅鬼鬼祟祟,一种罕见的组合:-)

【讨论】:

    【解决方案4】:

    尝试使用

    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
    【解决方案5】:
    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
    【解决方案6】:

    如果你有 pkill,

    pkill -f csp_build.py
    

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

    【讨论】:

      【解决方案7】:

      您只能使用pkill '^python*' 来杀死正则表达式进程。

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

      pgrep '^python*' | xargs kill

      【讨论】:

        【解决方案8】:

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

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

        【讨论】:

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

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

        【讨论】:

          【解决方案10】:

          杀死我们自己的进程从一个共同的 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
          

          【讨论】:

            【解决方案11】:

            ps 不需要用户切换。

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

            【讨论】:

              【解决方案12】:

              当 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 是错误的——它会错过任何不相邻的重复项,并通过对 输出进行不必要的排序来隐藏错误 i> uniq)。
              【解决方案13】:

              给 -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
              

              【讨论】:

                【解决方案14】:

                我使用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 脚本反模式。
                【解决方案15】:

                在某些情况下,我希望像这样同时终止进程:

                ➜ ~ 睡眠 1000 &
                [1] 25410
                ➜ ~ 睡 1000 &
                [2] 25415
                ➜ ~ 睡 1000 &
                [3] 25421
                ➜ ~ pidof 睡眠
                25421 25415 25410
                ➜ ~ 杀死`pidof sleep`
                [2] - 25415 终止睡眠 1000
                [1] - 25410 终止睡眠 1000
                [3] + 25421 终止睡眠 1000

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

                【讨论】:

                  【解决方案16】:

                  一个班轮:

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

                  • 打印第 2 列:awk '{print $2}'
                  • sudo 是可选的
                  • 运行kill -9 5124kill -9 5373 等(kill -15 更优雅但稍慢)

                  奖金:

                  我的 .bash_profile 中还定义了 2 个快捷功能 (~/.bash_profile 适用于 osx,您必须查看适用于您的 *nix 机器的内容)。

                  1. p 关键字
                    • 列出所有P包含关键字的进程
                    • 用法例如:p csp_buildp python

                  bash_profile 代码:

                  # FIND PROCESS
                  function p(){
                          ps aux | grep -i $1 | grep -v grep
                  }
                  
                  1. ka 关键字
                    • K生病了A所有具有此关键字的进程
                    • 用法例如:ka csp_buildka 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"
                  }
                  

                  【讨论】:

                    【解决方案17】:

                    我开始使用这样的东西:

                    kill $(pgrep 'python csp_build.py')
                    

                    【讨论】:

                      【解决方案18】:

                      使用 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
                      【解决方案19】:

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

                      kill -SIGTERM $(pgrep -i midori)

                      【讨论】:

                        【解决方案20】:

                        下面的命令会派上用场:

                        kill $(ps -elf | grep &lt;process_regex&gt;| 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'})

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

                        【讨论】:

                          【解决方案21】:

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

                          kill -9 $(ps -ef | grep '<exe_name>' | grep -v 'grep' | awk {'print $2'})
                          
                          • ps -ef | grep '&lt;exe_name&gt;' - 提供与模式匹配的正在运行的进程详细信息(uname、pid 等)列表。输出列表包括这个grep 命令也搜索它。现在为了杀死我们需要忽略这个grep 命令进程。
                          • ps -ef | grep '&lt;exec_name&gt;' | grep -v 'grep' - 使用 -v 'grep' 添加另一个 grep 会删除当前的 grep 进程。
                          • 然后使用awk单独获取进程ID。
                          • 然后将此命令保留在$(...) 中并将其传递给kill 命令,以终止所有进程。

                          【讨论】:

                            【解决方案22】:

                            您可以使用以下命令列出该命令的 pid。使用 top 或者更好的使用 htop 查看 linux 中的所有进程。这里我要杀死一个名为

                            的进程
                            ps -ef | grep '/usr/lib/something somelocation/some_process.js'  | grep -v grep | awk '{print $2}'
                            

                            并验证 pid。它必须是正确的。要杀死它们,请使用 kill 命令。

                            sudo kill -9 `ps -ef | grep '/usr/lib/something somelocation/some_process.js'  | grep -v grep | awk '{print $2}'`
                            

                            例如:- 来自 htop 进程列表。

                            sudo kill -9 `ps -ef | grep '<process>'  | grep -v grep | awk '{print $2}'`
                            

                            这解决了我的问题。如果您不小心杀死了一个进程,请始终准备好重新启动进程。

                            【讨论】:

                              【解决方案23】:

                              这将只返回 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)
                              

                              有关信号和 pgrep 的更多信息,请访问 man 7 signalman signalman pgrep

                              【讨论】:

                                【解决方案24】:

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

                                【讨论】:

                                  【解决方案25】:

                                  解决方案将过滤具有精确模式的进程,解析 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 - 终止或向进程发出信号

                                  数字 9 信号 - KILL(不可捕获,不可忽略的杀死)

                                  示例

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

                                  【讨论】:

                                  • 这是一个优秀(不太复杂)的答案和很好的描述/解释......
                                  【解决方案26】:

                                  使用ps 命令的-C 标志

                                  -C cmdlist
                                       Select by command name.  This selects the processes whose
                                       executable name is given in cmdlist.
                                  

                                  第一种情况,简单的命令

                                  因此,如果您通过 standard 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')
                                  

                                  【讨论】:

                                    【解决方案27】:

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

                                    【讨论】:

                                      【解决方案28】:

                                      基于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

                                      【讨论】:

                                        猜你喜欢
                                        • 1970-01-01
                                        • 2012-11-30
                                        • 2013-07-07
                                        • 1970-01-01
                                        • 2022-01-13
                                        • 1970-01-01
                                        • 2016-11-24
                                        • 2011-02-23
                                        • 1970-01-01
                                        相关资源
                                        最近更新 更多