题 如何杀死早于“t”的进程?


首先,是的,我已经看到了这个问题:

查找(并杀死)旧进程

那里的答案是不正确的,不起作用。我已经相应地投票和评论。

列出时,我要杀死的进程看起来像这样 ps aux | grep page.py

apache 424 0.0 0.1 6996 4564? S 07:02 0:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py
apache 2686 0.0 0.1 7000 3460? S Sep10 0:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py
apache 2926 0.0 0.0 6996 1404? S Sep02 0:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py
apache 7398 0.0 0.0 6996 1400? S Sep01 0:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py
apache 9423 0.0 0.1 6996 3824? S Sep10 0:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py
apache 11022 0.0 0.0 7004 1400? S Sep01 0:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py
apache 15343 0.0 0.1 7004 3788? S Sep09 0:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py
apache 15364 0.0 0.1 7004 3792? S Sep09 0:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py
apache 15397 0.0 0.1 6996 3788? S Sep09 0:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py
apache 16817 0.0 0.1 7000 3788? S Sep09 0:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py
apache 17590 0.0 0.0 7000 1432? S Sep07 0:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py
apache 24448 0.0 0.0 7000 1432? S Sep07 0:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py
apache 30361 0.0 0.1 6996 3776? S Sep09 0:00 /usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py

我正在设置一个简单的每日cron,它会找到并杀死任何一个 page.py 过程超过一小时。

上述问题的接受答案不起作用,因为它与一系列时间不匹配,它只是匹配从7天到7天23小时59分59秒运行的过程。我不想杀死已经运行1-2小时的进程,而是杀死任何东西 比...更棒 1小时。

使用上述问题的另一个答案 find 不起作用,至少不在Gentoo或CentOS 5.4上,它会发出警告,或者如果遵循所述警告的建议则不返回任何内容。


12
2017-09-15 17:05






答案:


GNU Killall可以使用其进程名杀死超过给定年龄的进程。

if [[ "$(uname)" = "Linux" ]];then killall --older-than 1h page.py;fi

18
2017-09-15 18:10



CentOS 6.6上没有该选项。版本:killall(PSmisc)22.6。 - Onnonymous


感谢克里斯托弗的回答,我能够将其改编为以下内容:

find /proc -maxdepth 1 -user apache -type d -mmin +60 -exec basename {} \; \
| xargs ps | grep page.py | awk '{ print $1 }' | sudo xargs kill

-mmin 是我失踪的发现命令。


8
2017-08-17 10:32



不确定-mmin是否适合检测过程的年龄。 - LatinSuD
它似乎没有出现/ proc /目录被修改很多,所以这似乎工作。话虽如此,我不想声称这是不可能的。 - Christopher Karel
我不认为这回答了你的问题,因为这个答案太狭隘,问题更广泛。 - poige
而且我会说更多 - 它根本不起作用: find /proc -maxdepth 1 -type d -name 1 -mmin +60 -ls  - / sbin / init没有列出,尽管正常运行时间是几天,而不是几小时。看来你不能依赖/ proc /的dirs修改时间。 - poige
遗憾的是,/ proc中的时间戳不能依赖于此。至少不再是这样了。 - dpk


发现并不总是有效,并非每个系统都有etimes可用,而且它可能是我的正则表达式newb状态,但我认为你不需要更多的东西:

ps -eo pid,etime,comm,user,tty | grep builder | grep pts | grep -v bash |awk '$2~/-/ {if ($2>7) print $1}'
  • 查找作为用户构建器运行的进程,从交互式登录pts执行,排除bash进程
  • 第二列将是经过的时间(etime)
  • 在第二列($ 2)上使用awk并在 - (ps etime打印格式为dd -hh:mm:ss)之前使用正则表达式(〜)字符串
  • 如果该值大于7(即运行超过7天),则打印第1列$ 1中的内容,即pid

然后,您可以管道杀死或任何您需要的东西。


6
2017-09-15 17:48



我认为这是一个更强大的解决方案,特别是在你的使用方面 ps,但我会折叠倍数 grep进入单身 awk,并且为了安全起见,将模式匹配到特定列(以排除例如命令名称匹配构建器等) - jmtd
当您的时间范围以天为单位时,这很好,但如果您想以小时,分钟或秒测试经过的时间,则无效。 - Vlastimil Ovčáčík


我认为您可以修改以前的一些答案以满足您的需求。即:

for FILE in(find.-maxdepth 1 -user processuser -type d -mmin +60)
  do kill -9 $(basename $ FILE)#我永远不会得到basename来使用find的exec。如果你知道如何,请告诉我!
DONE

要么

ps -eo pid,etime,comm | awk'$ 2!〜/^..:.. $ / && $ 3~ / page \ .py / {print $ 1}'|杀了-9

我认为第二种可能最适合您的需求。查找版本将结束该用户的其他进程


- 克里斯托弗卡雷尔


3
2018-05-29 06:20



不要用 kill -9 除非作为最后的手段。使用 -SIGINT 要么 -SIGTERM。 - Dennis Williamson
这是使用经过时间的格式作为测试标准,而不是其值。 ps 将输出时间 ^..:..$ 格式不到一小时。 - Vlastimil Ovčáčík


# get elapsed time in seconds, filter our only those who >= 3600 sec
ps axh -O etimes  | awk '{if ($2 >= 3600) print $2}'

如果你想要你可以喂 ps 用于在其中查找的PID列表,例如。 G。:

ps h -O etimes 1 2 3

3
2018-03-30 22:58



etimes 仅适用于较新的 ps - Tino


apt-get install psmisc

killall -o 1h $proc_name

2
2017-11-12 10:19



你能帮忙解释一下吗? psmisc 效用? OP提到CentOS;它是否可用作RPM? - Castaglia


问题

转换 etime (经过时间)列 ps 命令秒。时间规格采用这种格式 [[dd-]hh:]mm:ss。较新版本的 ps 有一个 etimes 输出的列 etime 以秒为单位的值。

解决方案:简单的自定义awk功能

这个自定义awk函数支持所有格式 etime 列(例如 03-12:30:5900:07 等等。)。只需将其粘贴到您的awk脚本中,它就是一个单行友好的解决方案。

function sec(T){C=split(T,A,"[:-]"); return A[C>3?C-3:99]*86400 + A[C>2?C-2:99]*3600 + A[C>1?C-1:99]*60 + A[C>0?C-0:99]*1}
  • sec(T) 将T转换为秒
  • T 时间规范 [[dd-]hh:]mm:ss 格式(例如 etime
  • C 中的字段数 T (相当于awk的NF变量)
  • A 中的一系列字段 T (相当于awk的$变量)
  • A[C>3?C-3:99] 这是以相反顺序引用第四个值(即天数)的安全方式。这种方法很有用,因为天和小时是可选的。如果数组不够长,则取消引用 A[99] 这将产生 0 值。我假设 99 对于大多数用例而言足够高。
  • 以整数形式返回秒数

现实世界的例子

这个bash oneliner会杀了 soffice.bin 如果进程超过180秒,则在当前用户下运行进程。

kill -9 $(ps cx -o command,etime,pid | awk '/^soffice.bin/ {if (sec($2)>180) {print $3}} function sec(T){C=split(T,A,"[:-]"); return A[C>3?C-3:99]*86400 + A[C>2?C-2:99]*3600 + A[C>1?C-1:99]*60 + A[C>0?C-0:99]*1}')

2
2017-09-15 23:25



对方的答案要好得多。它还处理多重触发。 - Denny Weinberg
最好在'ps'格式列表的末尾放置'command'或'args',以便能够在完整的命令/ args字符串上进行grep。将它放在开头将导致ps截断较长的命令。 - Maksym


lstart 在 ps 提供一致的时间格式,我们可以提供 date 从纪元开始转换为秒。然后我们将它与当前时间进行比较。

#!/bin/bash
current_time=$(date +%s)
ps axo lstart=,pid=,cmd= |
    grep page.py |
    while read line
    do
        # 60 * 60 is one hour, multiply additional or different factors for other thresholds 
        if (( $(date -d "${line:0:25}" +%s) < current_time - 60 * 60 ))
        then
            echo $line | cut -d ' ' -f 6    # change echo to kill
        fi
    done

1
2017-09-15 18:01





我在之前的帖子中修改了他们给你的答案

ps -eo pid,etime,comm | 
egrep '^ *[0-9]+ +([0-9]+-[^ ]*|[0-9]{2}:[0-9]{2}:[0-9]{2}) +/usr/bin/python2.6 /u/apps/pysnpp/current/bin/page.py' | 
awk '{print $1}' | 
xargs kill

正则表达式搜索2种类型的第二个参数:

  • 数字和减号形式的天数。
  • Hours:minutes:seconds 表达。

这应该匹配除了具有该形式的年轻进程之外的所有内容 minutes:seconds


0
2017-09-15 18:33



或者,我们可以像PS那样尝试。从/ proc / * / stat的第22个参数中提取/ proc / uptime的第一个参数。 - LatinSuD