你如何杀死所有超过一定年龄的Linux进程?

yuk*_*ude 66 unix linux bash process

我在某个服务器上遇到类似僵尸的进程有问题需要时不时地被杀死.如何才能最好地识别运行时间超过一小时的那些?

yuk*_*ude 36

找到一个适合我的答案:

警告:这将查找并终止长时间运行的进程

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

(其中user-id是具有长时间运行进程的特定用户ID.)

第二个正则表达式匹配具有可选天数的时间,后跟小时,分钟和秒组件,因此长度至少为一个小时.

  • 嗯,你杀了这个过程吗?我希望人们意识到这些代码不仅可以找到,而且可以杀死,或者他们可能会感到不安. (5认同)
  • 您可以使用选项`etimes`而不是`etime`来始终以秒为单位显示已用时间,而不是以天/小时为单位... (3认同)
  • WTF!请更改问题的标题.幸运的是,我没有拥有这个过程! (2认同)

小智 31

如果他们只是需要被杀死:

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

如果你想看看它匹配什么

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

-i对于每个进程匹配,该标志将提示您是/否.

  • 有什么意义`if [["$(uname)"="Linux"]];`?相关部分不仅仅是`killall`命令吗?(似乎可以删除周围的`if`子句以使这个答案更直接) (3认同)
  • 请注意,使用 killall 的 '--regex' 选项会导致忽略 '--older-than'。喜悦! (2认同)

Mar*_*son 22

对于任何超过一天的事物,

ps aux
Run Code Online (Sandbox Code Playgroud)

会给你答案,但它会降低到日精度,这可能没那么有用.

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]
Run Code Online (Sandbox Code Playgroud)

如果您使用的是/ proc文件系统的Linux或其他系统,在此示例中,您只能看到进程1自6月22日以来一直在运行,但没有指示它的启动时间.

stat /proc/<pid>
Run Code Online (Sandbox Code Playgroud)

会给你一个更准确的答案.例如,这是进程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
Run Code Online (Sandbox Code Playgroud)


gga*_*asp 9

通过这种方式,您可以获得十个最旧进程的列表:

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


g33*_*z0r 8

Jodie 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     
Run Code Online (Sandbox Code Playgroud)

这使您可以max_age使用完整的进程名称查找并终止超过秒的进程 ; 即,命名的进程/usr/bin/python2 offlineimap可以通过引用"offlineimap"来终止,而killall此处提供的解决方案仅适用于字符串"python2".


Pet*_*rch 7

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" } }'
Run Code Online (Sandbox Code Playgroud)

或者,格式化更多,将其放在名为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";
    }
}
Run Code Online (Sandbox Code Playgroud)

然后运行 perl process.pl

这为您提供了更多的多功能性和1秒的开始时间分辨率.