Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

First, yes I have seen this question:

The answers there are incorrect and do not work. I have voted and commented accordingly.

The processes I want to kill look like this when listed with ps aux | grep

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

I'm looking to setup a simple daily cron that will find and kill any processes older than an hour.

The accepted answer on the aforementioned question does not work, as it doesn't match a range of times, it simply matches processes that have been running from 7 days to 7 days 23 hours 59 minutes and 59 seconds. I don't want to kill processes that have been running from 1-2 hours, but rather anything greater than 1 hour.

The other answer to the aforementioned question using find does not work, at least not on Gentoo or CentOS 5.4, it either spits out a warning, or returns nothing if the advice of said warning is followed.

share|improve this question

14 Answers 14

GNU Killall can kill processes older than a given age, using their processname.

if [[ "$(uname)" = "Linux" ]];then killall --older-than 1h;fi
share|improve this answer
That option is not available on CentOS 6.6. Version: killall (PSmisc) 22.6. – Onnonymous Sep 28 '15 at 9:36
up vote 5 down vote accepted

Thanks to Christopher's answer I was able to adapt it to the following:

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

-mmin was the find command I was missing.

share|improve this answer
Not sure if -mmin is suitable for detecting the age of a process. – LatinSuD Sep 15 '10 at 18:19
It doesn't appear the /proc/ directories get modified a great deal, so this seems to work. That being said, I wouldn't want to claim it's impossible. – Christopher Karel Sep 15 '10 at 18:31
I don't think this answers your question since this answer is too narrow and question is wider. – poige May 29 '12 at 5:23
And I'd say even more — it doesn't work at all: find /proc -maxdepth 1 -type d -name 1 -mmin +60 -ls — /sbin/init isn't being listed in despite uptime counts for days, not hours. It seems you can't rely on /proc/'s dirs modification time. – poige May 29 '12 at 5:53
The timestamps in /proc can't be depended on for this, unfortunately. At least not any more. – dpk Jan 10 '13 at 21:46

I think you can modify some of those previous answers to fit your needs. Namely:

for FILE in (find . -maxdepth 1 -user processuser -type d -mmin +60)
  do kill -9 $(basename $FILE) # I can never get basename to work with find's exec.  Let me know if you know how!


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

I think the second may best fit your needs. The find version would wind up nuking other processes by that user

--Christopher Karel

share|improve this answer
Don't use kill -9 except as a last resort. Use -SIGINT or -SIGTERM. – Dennis Williamson Sep 15 '10 at 23:01

find doesnt always work, not every system has etimes available, and it might be my regex newb status, but I dont think you need anything more than this:

ps -eo pid,etime,comm,user,tty | grep builder | grep pts | grep -v bash |awk '$2~/-/ {if ($2>7) print $1}'
  • find process running as user builder, executed from interactive login pts, exclude bash processes
  • the second column will be the elapsed time (etime)
  • use awk on the 2nd column ($2) and get with a regex (~) the string before the -(ps etime prints in format dd-hh:mm:ss)
  • If that value is larger than 7 (ie, been running more than seven days) print what is in the first column $1 , ie pid

you can then pipe that to kill or whatever your need may be.

share|improve this answer
I think this is one of the more robust solutions, especially in terms of your use of ps, but I'd fold the multiple greps into the single awk, and for safety restrict the pattern matches to particular columns (to rule out e.g. a command name matching builder, etc.) – jmtd Feb 6 '13 at 16:08

The lstart field in ps gives a consistent time format which we can feed to date to convert to seconds since the epoch. Then we just compare that to the current time.

current_time=$(date +%s)
ps axo lstart=,pid=,cmd= |
    grep |
    while read line
        # 60 * 60 is one hour, multiply additional or different factors for other thresholds 
        if (( $(date -d "${line:0:25}" +%s) < current_time - 60 * 60 ))
            echo $line | cut -d ' ' -f 6    # change echo to kill
share|improve this answer
# get elapsed time in seconds, filter our only those who >= 3600 sec
ps axh -O etimes  | awk '{if ($2 >= 3600) print $2}'

If you wan't you can feed ps with list of PIDs to lookup within, for e. g.:

ps h -O etimes 1 2 3
share|improve this answer
etimes works only for newer ps – Tino Jul 18 '15 at 21:45

I modified the answer they gave you in previous post

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/' | 
awk '{print $1}' | 
xargs kill

The regular expression searches for 2 types of second argument:

  • Days in the form of digits and a minus sign.
  • Hours:minutes:seconds expression.

That should match everything except young processes who would have the form minutes:seconds.

share|improve this answer
Alternatively we could try do it the way PS does it. Substract the first argument of /proc/uptime from the 22nd argument of /proc/*/stat. – LatinSuD Sep 15 '10 at 18:44

This is probably overkill, but I got curious enough to finish it and test that it works (on a different process name on my system, of course). You can kill the capturing of $user and $pid to simplify the regexp, which I only added for debugging, and didn't feel like ripping back out. Named captures from perl 5.10 would shave off a couple more lines, but this should work on older perls.

You'll need to replace the print with a kill, of course, but I wasn't about to actually kill anything on my own system.

#!/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 = '';                                                   

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";                                                               

share|improve this answer

I have a server with wrong dates in /proc and find doesn't work so I wrote this script:


MAX_DAYS=7  #set the max days you want here
MAX_TIME=$(( $(date +'%s') - $((60*60*24*$MAX_DAYS)) ))

function search_and_destroy()
        for p in $(ps ux|grep "$PATTERN"|grep -v grep| awk '{ print $2 }')
            test $(( $MAX_TIME - $(date -d "`ps -p $p -o lstart=`" +'%s') )) -ge 0 && kill -9 $p

search_and_destroy " command1 "
search_and_destroy " command2 "
share|improve this answer

Python version using the ctime of the process entries in /proc:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# kills processes older than HOURS_DELTA hours

import os, time


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:
            os.kill(pid, SIGNAL)
            print "Couldn't kill process %d" % pid
share|improve this answer

I use this simple script it takes two arguments name of process and age in seconds.

# first argument name of the process to check
# second argument maximum age in seconds
# i.e kill lighttpd after 5 minutes
# lighttpd 300 
pid=`pgrep $process`
if [ $? -ne 0 ]
        exit 0
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 ]
        kill -3 $pid
share|improve this answer
apt-get install psmisc

killall -o 1h $proc_name
share|improve this answer
Could you help explain more about the psmisc utility? The OP mentioned CentOS; is it available as an RPM? – Castaglia Mar 31 at 4:22

72=3days 48=2days 24=1day

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

it works :)

share|improve this answer
That may well be, but it's pretty difficult to read and learn from. Consider reformatting with some newlines and stuff... scripts are better than one-liners for instruction. – Falcon Momot Apr 25 '15 at 7:51

this should work

killall --older-than 1h $proc_name

share|improve this answer
How does this add or improve [the already existing answers]? – Reaces Oct 12 '15 at 14:02
@Reaces: In all fairness, I had to search for the one answer mentioning --older-than and it's easy to overlook it. Compared to the other answers, this is much easier, and it's available now on EL7 as well. – Sven Oct 12 '15 at 14:21
@Reaces this just makes it easier than writing scripts using awk/sed etc to kill a process, this i suppose is much simpler and cleaner – Jabir Ahmed Oct 27 '15 at 16:09

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.