How do you kill all Linux processes that are older

2019-01-08 08:12发布

I have a problem with some zombie-like processes on a certain server that need to be killed every now and then. How can I best identify the ones that have run for longer than an hour or so?

14条回答
我欲成王,谁敢阻挡
2楼-- · 2019-01-08 08:39

You can use bc to join the two commands in mob's answer and get how many seconds ellapsed since the process started:

echo `date +%s` - `stat -t /proc/<pid> | awk '{print $14}'` | bc

edit:

Out of boredom while waiting for long processes to run, this is what came out after a few minutes fiddling:

#file: sincetime
#!/bin/bash
init=`stat -t /proc/$1 | awk '{print $14}'`
curr=`date +%s`
seconds=`echo $curr - $init| bc`
name=`cat /proc/$1/cmdline`
echo $name $seconds

If you put this on your path and call it like this: sincetime

it will print the process cmdline and seconds since started. You can also put this in your path:

#file: greptime
#!/bin/bash
pidlist=`ps ax | grep -i -E $1 | grep -v grep | awk '{print $1}' | grep -v PID | xargs echo`
for pid in $pidlist; do
    sincetime $pid
done

And than if you run:

greptime <pattern>

where patterns is a string or extended regular expression, it will print out all processes matching this pattern and the seconds since they started. :)

查看更多
戒情不戒烟
3楼-- · 2019-01-08 08:41

Perl's Proc::ProcessTable will do the trick: http://search.cpan.org/dist/Proc-ProcessTable/

You can install it in debian or ubuntu with sudo apt-get install libproc-processtable-perl

Here is a one-liner:

perl -MProc::ProcessTable -Mstrict -w -e 'my $anHourAgo = time-60*60; my $t = new Proc::ProcessTable;foreach my $p ( @{$t->table} ) { if ($p->start() < $anHourAgo) { print $p->pid, "\n" } }'

Or, more formatted, put this in a file called process.pl:

#!/usr/bin/perl -w
use strict;
use Proc::ProcessTable;
my $anHourAgo = time-60*60;
my $t = new Proc::ProcessTable;
foreach my $p ( @{$t->table} ) {
    if ($p->start() < $anHourAgo) {
        print $p->pid, "\n";
    }
}

then run perl process.pl

This gives you more versatility and 1-second-resolution on start time.

查看更多
萌系小妹纸
4楼-- · 2019-01-08 08:46

In case anyone needs this in C, you can use readproc.h and libproc:

#include <proc/readproc.h>
#include <proc/sysinfo.h>

float
pid_age(pid_t pid)
{
        proc_t proc_info;
        int seconds_since_boot = uptime(0,0);
        if (!get_proc_stats(pid, &proc_info)) {
                return 0.0;
        }

        // readproc.h comment lies about what proc_t.start_time is. It's
        // actually expressed in Hertz ticks since boot

        int  seconds_since_1970 = time(NULL);
        int time_of_boot = seconds_since_1970 - seconds_since_boot;
        long  t = seconds_since_boot - (unsigned long)(proc_info.start_time / Hertz);

        int delta = t;
        float days = ((float) delta / (float)(60*60*24));
        return days;
}
查看更多
对你真心纯属浪费
5楼-- · 2019-01-08 08:47

do a ps -aef. this will show you the time at which the process started. Then using the date command find the current time. Calculate the difference between the two to find the age of the process.

查看更多
成全新的幸福
6楼-- · 2019-01-08 08:47

Came across somewhere..thought it is simple and useful

You can use the command in crontab directly ,

* * * * * ps -lf | grep "user" |  perl -ane '($h,$m,$s) = split /:/,$F
+[13]; kill 9, $F[3] if ($h > 1);'

or, we can write it as shell script ,

#!/bin/sh
# longprockill.sh
ps -lf | grep "user" |  perl -ane '($h,$m,$s) = split /:/,$F[13]; kill
+ 9, $F[3] if ($h > 1);'

And call it crontab like so,

* * * * * longprockill.sh
查看更多
Viruses.
7楼-- · 2019-01-08 08:48

stat -t /proc/<pid> | awk '{print $14}'

to get the start time of the process in seconds since the epoch. Compare with current time (date +%s) to get the current age of the process.

查看更多
登录 后发表回答