杀死所有早于x的进程,匹配正则表达式

时间:2017-03-06 09:56:12

标签: bash ubuntu kill

我试图通过早于x的正则表达式来杀死所有进程 - 但是找不到进程!

dep@srv-05:~$ ps aux | grep sidekiq

dep  6154 65.5  4.8 4652148 3170540 ?     Ssl  10:00  32:35 sidekiq 4.2.6 au [1 of 8 busy] stopping
dep  6172 80.8  4.3 4462376 2897480 ?     Ssl  10:20  23:52 sidekiq 4.2.6 au [8 of 8 busy]
dep  9099 89.9  1.7 2216372 1167664 ?     Ssl  10:48   1:23 sidekiq 4.2.6 au [8 of 8 busy]
dep  9548 86.8  1.6 2624832 1097428 ?     Ssl  10:48   1:16 sidekiq 4.2.6 au [8 of 8 busy]
dep 14196  0.0  0.0  13224  2076 pts/17   S+   10:50   0:00 grep --color=auto sidekiq
dep 21933 84.8  4.2 4342940 2792592 ?     Ssl  10:41   7:34 sidekiq 4.2.6 au [8 of 8 busy]
dep 26466 29.5  5.8 5116960 3822876 ?     Ssl  09:07  30:18 sidekiq 4.2.6 au [1 of 8 busy] stopping
dep 27790 64.3  4.8 5074216 3210584 ?     Ssl  09:58  33:34 sidekiq 4.2.6 au [3 of 8 busy] stopping
dep 29695 87.4  3.1 3405204 2094332 ?     Ssl  10:44   4:53 sidekiq 4.2.6 au [7 of 8 busy]
dep 29850  0.2  5.0 4663268 3296372 ?     Ssl  mar02  12:42 sidekiq 4.2.6 au [1 of 8 busy] stopping
dep 29919 87.5  2.7 3207616 1805844 ?     Ssl  10:45   4:35 sidekiq 4.2.6 au [8 of 8 busy]

dep@srv-05:~$ killall -o 24h -r sidekiq.*au.*stopping
sidekiq.*au.*stopping: no process found

但它不能以某种方式工作?

更新

删除-o 24h无效:

dep@srv-05:~$ killall -r sidekiq.*au.*stopping
sidekiq.*au.*stopping: no process found

1 个答案:

答案 0 :(得分:1)

我写了thing关于此事。

killall

无需检查命令args 时,将是完美的工具,只考虑进程名称。

  

-o, - older-than         仅匹配较早( 之前开始)时间的流程         的指定即可。时间被指定为浮点数然后是单位。该         单位是秒,分,小时,天,s,m,h,d,w,M,y,         几周,几个月和几年。

     

-r, - regexp         将进程名称模式解释为扩展正则表达式。

pkill

示例:

pkill -f "sidekiq.*au.*stopping"

解决隐藏参数的问题

  

-f将模式匹配进程的完整参数字符串中的任何位置,而不仅仅是可执行文件名。

没有提供按经过时间对流程进行排序的方法。

所以......让我们构建我们的自定义解决方案。

让我们回到一位老朋友ps

来自 man 页面:

  

-e选择所有流程。

     

-o格式用户定义的格式。

AIX FORMAT DESCRIPTORS

  

这个ps支持AIX格式描述符,它的工作方式有点像printf(1)和printf(3)的格式代码。    例如,可以使用以下方法生成正常的默认输出:     ps -eo "%p %y %x %c"

   CODE   NORMAL   HEADER
   %C     pcpu     %CPU
   %G     group    GROUP
   %P     ppid     PPID
   %U     user     USER
   %a     args     COMMAND
   %c     comm     COMMAND
   %g     rgroup   RGROUP
   %n     nice     NI
   %p     pid      PID
   %r     pgid     PGID
   %t     etime    ELAPSED
   %u     ruser    RUSER
   %x     time     TIME
   %y     tty      TTY
   %z     vsz      VSZ

首先,要 杀死 一个进程,我们需要的是它的PID,然后知道它运行了多长时间,最后是命令名称和它是args。

这可以通过使用上表中提到的代码的格式字符串来完成:

ps -eo "%p>~<%t>~<%a"

注意:选择复杂字符串作为字段>~<之间的分隔符非常重要,我们不希望在命令中找到相同的字符串名字或args使我们的数据混乱。

要处理此输出,我们将逐步构建awk oneliner。

如何让进程运行+ 24h?

ps手册页中:

  

etime自流程启动以来经过的已用时间,格式为[[dd-]hh:]mm:ss

因此,第二个字段中一个破折号字符表示该程序已运行至少24小时。

示例:

$ ps -eo "%p>~<%t>~<%a" | awk -v '$2 ~ /-/' FS='>~<'
  528>~<49-04:37:37>~</sbin/udevd -d
  746>~<21-08:21:52>~</dummys/apache/bin/rotatelogs -f /logs/access_log800 86400
  747>~<21-08:21:52>~</dummys/apache/bin/rotatelogs -f /logs/access_log445 86400
  748>~<21-08:21:52>~</dummys/apache/bin/rotatelogs -f /logs/access_log1447 86400
  749>~<21-08:21:52>~</dummys/apache/bin/rotatelogs -f /logs/access_log450 86400
 2170>~<49-04:37:14>~</sbin/rsyslogd -i /var/run/syslogd.pid -c 5
 2204>~<49-04:37:14>~<irqbalance --pid=/var/run/irqbalance.pid
 2270>~<49-04:37:14>~</usr/sbin/mcelog --daemon
 6892>~<49-04:37:01>~</usr/sbin/snmpd -LS0-6d -Lf /dev/null -p /var/run/snmpd.pid
 6920>~<49-04:37:01>~<xinetd -stayalive -pidfile /var/run/xinetd.pid

注意FS设置为ps格式使用的字符串:>~<

命令行是否与我们的 regexp 匹配?

最后一步,检查command + args%a)是否包含我们的regexp,本示例中 rotatelogs 字符串。< / p>

$ ps -eo "%p>~<%t>~<%a" | awk -v r="rotate.*access.*" '$2 ~ /-/ && $3 ~ r' FS='>~<'
  746>~<21-08:21:52>~</dummys/apache/bin/rotatelogs -f /logs/access_log800 86400
  747>~<21-08:21:52>~</dummys/apache/bin/rotatelogs -f /logs/access_log445 86400
  748>~<21-08:21:52>~</dummys/apache/bin/rotatelogs -f /logs/access_log1447 86400
  749>~<21-08:21:52>~</dummys/apache/bin/rotatelogs -f /logs/access_log450 86400

让我们只打印pids。

$ ps -eo "%p>~<%t>~<%a" |\
   awk -v r="rotate.*access.*" '$2 ~ /-/ && $3 ~ r{printf "%d ",$1}' FS='>~<'
  746 747 748 749

Bash command substituion 将成为最后一招。

$ kill $(ps -eo "%p>~<%t>~<%a" |\
  awk -v r="rotate.*access.*" '$2 ~ /-/ && $3 ~ r{printf "%d ",$1}' FS='>~<')

对于您的情况

kill $(ps -eo "%p>~<%t>~<%c %a"|\
  gawk -v r="sidekiq.*au.*stopping" '$2~/-/ && $3 ~ r{print $1}' FS='>~<')

如果您希望最精细控制appargs值:

kill $(ps -eo "%p>~<%t>~<%c>~<%a"|\
         gawk -v app="sidekiq" -v args="au.*stopping" '$2~/-/ &&  $3 ~ app && $4 ~ args{printf "%d ",$1}' FS='>~<')