我试图通过早于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
答案 0 :(得分:1)
我写了thing关于此事。
当无需检查命令args 时,将是完美的工具,只考虑进程名称。
-o, - older-than 仅匹配较早( 之前开始)时间的流程 的指定即可。时间被指定为浮点数然后是单位。该 单位是秒,分,小时,天,s,m,h,d,w,M,y, 几周,几个月和几年。
-r, - regexp 将进程名称模式解释为扩展正则表达式。
示例:
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。
在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
格式使用的字符串:>~<
最后一步,检查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='>~<')
如果您希望最精细控制app
和args
值:
kill $(ps -eo "%p>~<%t>~<%c>~<%a"|\
gawk -v app="sidekiq" -v args="au.*stopping" '$2~/-/ && $3 ~ app && $4 ~ args{printf "%d ",$1}' FS='>~<')