67

特定のサーバーで、時々強制終了する必要があるゾンビのようなプロセスに問題があります。1 時間以上実行されているものを特定するにはどうすればよいでしょうか?

4

14 に答える 14

36

私に役立つ答えを見つけました:

警告: これは実行時間の長いプロセスを見つけて強制終了します

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

( user-idは、実行時間の長いプロセスを持つ特定のユーザーの ID です。)

2 番目の正規表現は、オプションの日数の後に時間、分、秒のコンポーネントが続く時間に一致し、少なくとも 1 時間の長さになります。

于 2008-08-08T17:03:56.850 に答える
34

彼らが殺される必要がある場合:

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

何が合ってるか見たいなら

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

フラグは、-iプロセスが一致するたびに yes/no でプロンプトを表示します。

于 2012-05-09T23:50:32.473 に答える
22

1 日より古いものについては、

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 が 6 月 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
于 2008-08-08T16:56:56.880 に答える
9

このようにして、最も古い 10 個のプロセスのリストを取得できます。

ps -エルフ | 並べ替え -r -k12 | 頭 -n 10
于 2008-08-08T17:20:01.917 に答える
8

killall -iJodie C と他の人は、プロセス名を使用して強制終了したい場合に使用できると指摘しています。しかし、 と同じパラメータで強制終了したい場合は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を使用して数秒以上前のプロセスを見つけて強制終了できます。つまり、指定されたプロセスは「offlineimap」を参照することで強制終了できますが、ここで示す解決策は文字列「python2」でのみ機能します。/usr/bin/python2 offlineimapkillall

于 2013-05-14T15:54:11.633 に答える
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" } }'

または、よりフォーマット化して、これを 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 秒単位になります。

于 2010-08-13T07:19:40.447 に答える
2

を行いますps -aef。これにより、プロセスが開始された時刻が表示されます。次に、dateコマンドを使用して現在の時刻を検索します。プロセスの経過時間を見つけるために、2つの間の差を計算します。

于 2009-10-24T02:49:34.603 に答える
1

プロセス名と100秒以上実行されている不良プロセスに基づいて照合したいので、受け入れられた回答と似ていますが、少し異なります。

kill $(ps -o pid,bsdtime -p $(pgrep bad_process) | awk '{ if ($RN > 1 && $2 > 100) { print $1; }}')
于 2011-08-11T03:15:05.837 に答える
1

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

エポックからのプロセスの開始時刻を秒単位で取得します。現在の時刻 ( ) と比較してdate +%s、プロセスの現在の経過時間を取得します。

于 2012-02-16T17:39:07.747 に答える
0

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;
}
于 2012-04-02T09:07:24.583 に答える
0

ps を使用するのが正しい方法です。以前にも同様のことを行ったことがありますが、ソースが手元にありません。一般に、ps には、表示するフィールドとソートするフィールドを指定するオプションがあります。出力を実行時間でソートし、必要なプロセスをgrepしてから強制終了できます。

HTH

于 2008-08-08T16:54:49.643 に答える