我有一个问题与一些僵尸般的进程上的某些服务器,需要被杀害。如何才能最好地确定那些必须运行时间超过一个小时左右?

有帮助吗?

解决方案

如果他们只需要被杀害:

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

如果你想看到什么这是匹配的

if [[ "$(uname)" = "Linux" ]];then killall -i --older-than 1h someprocessname;fi

-i 标志会提示你是/否为每个过程相匹配。

其他提示

找到一个答案对我的作品:

警告:这将找到 和杀死 长期运行的流程

ps -eo uid,pid,etime | egrep '^ *user-id' | egrep ' ([0-9]+-)?([0-9]{2}:?){3}' | awk '{print $2}' | xargs -I{} kill {}

(在那里 用户名 是一个特定用户的标识与长期运行的进程。)

第二个定期表达相匹配的时间,有一个可选择的日子图,随后一个小时,分钟,第二部件,因此至少一个小时的长度。

为什么超过一天,

ps aux

会给你的答案,但是它降下来的一天-精密的不可能作为有用的。

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0   7200   308 ?        Ss   Jun22   0:02 init [5]
root         2  0.0  0.0      0     0 ?        S    Jun22   0:02 [migration/0]
root         3  0.0  0.0      0     0 ?        SN   Jun22   0:18 [ksoftirqd/0]
root         4  0.0  0.0      0     0 ?        S    Jun22   0:00 [watchdog/0]

如果你在linux或另一个系统/proc文件系统,在这个例子中,你只能看到这一进程的1已经运行以来的六月22日,但没有指示的时间是开始。

stat /proc/<pid>

会给你一个更加精确的答案。例如,这是一个确切的时间戳,用于处理1,其ps显示了仅为Jun22:

ohm ~$ stat /proc/1
  File: `/proc/1'
  Size: 0               Blocks: 0          IO Block: 4096   directory
Device: 3h/3d   Inode: 65538       Links: 5
Access: (0555/dr-xr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2008-06-22 15:37:44.347627750 -0700
Modify: 2008-06-22 15:37:44.347627750 -0700
Change: 2008-06-22 15:37:44.347627750 -0700

在这种方式可以获得该名单的十个古老的过程:

ps -elf | sort -r -k12 | head -n 10

朱迪C和其他人已经指出, killall -i 可以使用,这是好的如果你想使用的进程名称的杀人。但如果你想杀了通过相同的参数 pgrep -f, 你需要使用类似于以下,采用纯bash和 /proc 文件系统。

#!/bin/sh                                                                                                                                               

max_age=120 # (seconds)                                                                                                                                 
naughty="$(pgrep -f offlineimap)"                                                                                                                       
if [[ -n "$naughty" ]]; then # naughty is running                                                                                                       
  age_in_seconds=$(echo "$(date +%s) - $(stat -c %X /proc/$naughty)" | bc)                                                                              
  if [[ "$age_in_seconds" -ge "$max_age" ]]; then # naughty is too old!                                                                                 
    kill -s 9 "$naughty"                                                                                                                                
  fi                                                                                                                                                    
fi     

这可以让你找到杀死的过程早于 max_age 几秒钟内使用的 完整的过程的名字;即,工命名的 /usr/bin/python2 offlineimap 可以杀死了通过参考"offlineimap",而 killall 解决方案提出这里,只会的工作string"python2".

Perl的Proc::ProcessTable会做的把戏:http://search.cpan.org/dist/Proc-ProcessTable/

你可以安装在debian或ubuntu与 sudo apt-get install libproc-processtable-perl

这里是一个一衬:

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

或者,更多的格式,把这个放在一个文件叫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";
    }
}

然后运行 perl process.pl

这给你更多的灵活性和1-二号决议开始的时间。

你可以使用 bc 加入两条命令在暴徒的回答,并得到多少秒ellapsed由于进程的开始:

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

编辑:

无聊的话,等待漫长的进程的运行,这是什么出来之后几分钟摆弄:

#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

如果你把这个放在你的道路,并呼吁它这样的:sincetime

它将印刷过程的命令行和秒从开始。你也可以把这个放在你的路径:

#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

和比,如果你的运行:

greptime <pattern>

其模式是一串或延长经常表达,它将打印出所有进程相匹配这个图案和秒钟,因为它们启动。:)

做一个 ps -aef.这会告诉你的时间进程的开始。然后使用 date 命令发现的当前时间。计算差值两者之间找到时代的过程。

我做了一件类似于接受的答案,但略有不同,因为我想要匹配的基础上处理名称并根据坏的进程的运行超过100秒

kill $(ps -o pid,bsdtime -p $(pgrep bad_process) | awk '{ if ($RN > 1 && $2 > 100) { print $1; }}')

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

获得的启动时间的过程中在几秒钟内由于时代。比较与当前的时间(date +%s)获得当前年龄的进程。

使用ps是正确的方式。我已经做过类似的东西之前,但没有来源的方便。一般-ps有一个选项,告诉它它领域,以显示和通过其排序。你可以由输出运行的时间查询这个过程中你想要的然后杀了它。

禾田

在情况下,任何人都需要这一C,可以使用readproc.h和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;
}

碰到的地方..认为这是简单和有用的

你可以使用的命令务直接,

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

或者,我们可以把它写作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);'

并呼吁这务喜欢这样,

* * * * * longprockill.sh

我的版本 sincetime 上通过@拉斐尔*S.Calsaverini:

#!/bin/bash
ps --no-headers -o etimes,args "$1"

这逆转的产出领域:经过时间的第一、完整的命令包括的参数第二。这是首选,因为完整的命令可以包含空间。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top