如何杀死比“t”更早的进程?

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

查找(并杀死)旧的进程

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

ps aux | grep page.py列出我想要杀死的进程 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的上述问题的其他答案不起作用,至less在Gentoo或CentOS 5.4上不行,它要么发出警告,要么按照所述警告的build议返回。

GNU Killall可以使用他们的进程名杀死比特定年龄更早的进程。

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

感谢克里斯托弗的回答,我能够适应以下几点:

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

-mmin是我找不到的命令。

发现并不总是工作,并不是每个系统都有etimes可用,这可能是我的正则expression式newb状态,但我不认为你需要任何比这更多的东西:

 ps -eo pid,etime,comm,user,tty | grep builder | grep pts | grep -v bash |awk '$2~/-/ {if ($2>7) print $1}' 
  • find进程作为用户构build器运行,从交互式loginpts执行,排除bash进程
  • 第二列将是经过的时间(etime)
  • 在第二列使用awk($ 2),并在 – (ps etime以dd-hh:mm:ss格式打印)之前用正则expression式(〜)得到string。
  • 如果该值大于7(即已经运行超过七天),则打印第一列$ 1中的内容,即pid

那么你可以通过pipe道来杀死或者任何你需要的东西。

我想你可以修改一些以前的答案,以适应您的需求。 即:

 (find。-maxdepth 1 -user processuser -type d -mmin +60)
  杀死-9 $(basename $ FILE)#我永远不能得到基地名称与查找的执行。 让我知道如果你知道如何!
 DONE 

要么

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

我认为第二个最适合你的需要。 查找版本将结束该用户的其他进程

– 克里斯托弗·卡雷尔

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

如果你想要的话,可以在ps PID列表来查找,例如:

 ps h -O etimes 1 2 3 
 apt-get install psmisc killall -o 1h $proc_name 

pslstart字段提供了一个一致的时间格式,我们可以将其转换为自时代以来的秒数。 然后,我们只是比较当前的时间。

 #!/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 

问题

ps命令的etime (经过时间)列转换为秒。 时间指定格式为[[dd-]hh:]mm:ss 。 较新版本的ps有一个etimes列,它在几秒钟内输出etime值。

解决方法:简单的自定义awk函数

这个自定义的awk函数支持所有格式的etime列(例如03-12:30:59等)。 只要把它粘贴在你的awk脚本中,这是一个友好的解决scheme。

 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转换为秒
  • [[dd-]hh:]mm:ss格式(例如etime
  • T中字段C计数(相当于awk的NFvariables)
  • T A数组(相当于awk的$variables)
  • A[C>3?C-3:99]这是以相反顺序引用第四个值(即天数)的安全方法。 这种方法很有用,因为date和时间是可选的。 如果数组不够长,则解引用A[99] ,这将产生0值。 我认为99对于大多数用例来说足够高。
  • 以整数forms返回秒

真实世界的例子

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

 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}') 

我在之前的文章中修改了他们给你的答案

 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 

正则expression式search2种第二个参数:

  • 数字和减号forms的日子。
  • Hours:minutes:secondsexpression。

这应该匹配除了年轻的进程谁会有minutes:seconds的formsminutes:seconds

这可能是矫枉过正,但我​​很好奇,完成它,并testing它的工作(当然,在我的系统上不同的进程名称)。 你可以杀死$user$pid的捕获,以简化正则expression式,我只是为了debugging而添加的,而不是像抓取一样。 来自Perl 5.10的命名捕获将削减更多的线,但这应该适用于更老的perls。

当然,你需要用杀手来代替打印,但是我并不想在自己的系统上杀死任何东西。

 #!/usr/bin/perl -T use strict; use warnings; $ENV{"PATH"} = "/usr/bin:/bin"; my (undef,undef,$hour) = localtime(time); my $target = $hour - 2; # Flag process before this hour my $grep = 'page.py'; my @proclist = `ps -ef | grep $grep`; foreach my $proc (@proclist) { $proc =~ /(\w+)\s+(\d+)\s+\d+\s+\d+\s+(.*?).*/; my $user = $1; my $pid = $2; my $stime = $3; $stime =~ s/(\d+):(\d+)/$1/; # We're going to do a numeric compare against strings that # potentially compare things like 'Aug01' when the STIME is old # enough. We don't care, and we want to catch those old pids, so # we just turn the warnings off inside this foreach. no warnings 'numeric'; unless ($stime > $target) { print "$pid\n"; } } 

我在/ proc中有一个错误date的服务器,并且找不到,所以我写了这个脚本:

 #!/bin/bash MAX_DAYS=7 #set the max days you want here MAX_TIME=$(( $(date +'%s') - $((60*60*24*$MAX_DAYS)) )) function search_and_destroy() { PATTERN=$1 for p in $(ps ux|grep "$PATTERN"|grep -v grep| awk '{ print $2 }') do test $(( $MAX_TIME - $(date -d "`ps -p $p -o lstart=`" +'%s') )) -ge 0 && kill -9 $p done } search_and_destroy " command1 " search_and_destroy " command2 " 

Python版本使用/proc中的进程条目的ctime:

 #!/usr/bin/env python # -*- coding: utf-8 -*- # kills processes older than HOURS_DELTA hours import os, time SIGNAL=15 HOURS_DELTA=1 pids = [int(pid) for pid in os.listdir('/proc') if pid.isdigit()] for pid in pids: if os.stat(os.path.join('/proc', str(pid))).st_ctime < time.time() - HOURS_DELTA * 3600: try: os.kill(pid, SIGNAL) except: print "Couldn't kill process %d" % pid 

我使用这个简单的脚本,它需要两个参数名称的进程和年龄在几秒钟内。

 #!/bin/bash # first argument name of the process to check # second argument maximum age in seconds # ie kill lighttpd after 5 minutes # script.sh lighttpd 300 process=$1 maximum_runtime=$2 pid=`pgrep $process` if [ $? -ne 0 ] then exit 0 fi process_start_time=`stat /proc/$pid/cmdline --printf '%X'` current_time=`date +%s` let diff=$current_time-$process_start_time if [ $diff -gt $maximum_runtime ] then kill -3 $pid fi 

我对另一个解决scheme并不满意,其中大部分都太神秘了(我的bash知识有限),所以我不能定制它们。
我已经创build了自己的解决scheme,它可能不是最好的,但它的工作原理和可读性

你可以将这个脚本保存在一个文件中,并使其可执行(最终使用cron调用它)

 #!/bin/bash ## time in second that trigger the kill LIMIT=10 ## [] skip the grep from the process list PROC_NAME="[m]y process name" ## etimes return the time in seconds TIME_SEC=$(ps axo etimes,pid,command | grep "$PROC_NAME" | awk {'print$1'}) PID=$(ps axo etimes,pid,command | grep "$PROC_NAME" | awk {'print$2'}) if [ -n "$TIME_SEC" ] then if (( $TIME_SEC > $LIMIT )); then kill $PID fi fi 

这应该工作

killall --older-than 1h $proc_name

72 = 3天48 = 2天24 = 1天

 a1=$(TZ=72 date +%d) ps -ef| cat filex.txt | sed '/[JFMASOND][aepuco][nbrylgptvc] '$a1'/!d' | awk '{ print $2 " " $5 " " $6 }' > file2.txt 

有用 :)