Vra

Ek het 'n probleem met 'n paar zombie-agtige prosesse op 'n sekere bediener wat aangespreek moet word vermoor elke nou en dan. Hoe kan ek die beste identifiseer dié wat gehardloop het vir langer as 'n uur of so?

Was dit nuttig?

Oplossing

As hulle nodig het net om doodgemaak te word:

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

As jy wil om te sien wat dit is wat ooreenstem met die

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

Die -i vlag sal jy gevra word met ja / nee vir elke proses wedstryd.

Ander wenke

Het jy 'n antwoord wat vir my:

Waarskuwing: hierdie sal vind en dood te maak lang loop prosesse

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

(Waar gebruiker-id is ID 'n spesifieke gebruiker se met 'n lang-lopende prosesse.)

Die tweede regular expression ooreenstem met die tyd wat 'n opsionele dae figuur, gevolg deur 'n uur, minuut, en tweede komponent het, en so is ten minste een uur lank.

Vir enigiets ouer as een dag,

ps aux

sal jy die antwoord gee, maar dit daal af na dag-presisie wat nie as nuttig kan wees.

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]

As jy op linux of 'n ander stelsel met die / processed lêerstelsel, In hierdie voorbeeld, jy kan net sien dat die proses 1 is reeds sedert 22 Junie, maar geen aanduiding van die tyd wat dit begin.

stat /proc/<pid>

sal jy 'n meer akkurate antwoord gee. Byvoorbeeld, hier is 'n presiese datum en tyd vir die proses 1, wat ps wys net as 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

In hierdie manier kan jy die lys van die tien oudste prosesse te verkry:

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

Jodie C en ander het daarop gewys dat killall -i gebruik kan word, wat is goed as jy wil om die naam te gebruik om dood te maak. Maar as jy wil om dood te maak deur dieselfde parameters as pgrep -f, moet jy iets soos die volgende gebruik, met behulp van suiwer bash en die /proc lêerstelsel.

#!/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     

Dit laat jou te vind en prosesse ouer as max_age sekondes met behulp van die volle proses naam doodmaak ; dit wil sê, kan die proses genoem /usr/bin/python2 offlineimap doodgemaak word deur verwysing na "offlineimap", terwyl die killall oplossings wat hier aangebied word slegs sal werk op die string "python2".

Perl se Proc :: ProcessTable sal die truuk doen: http://search.cpan.org/dist/Proc-ProcessTable/

Jy kan dit in Debian of ubuntu installeer met sudo apt-get install libproc-processtable-perl

Hier is 'n 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" } }'

Of, meer formaat, sit dit in 'n lêer met die naam 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";
    }
}

dan hardloop perl process.pl

Dit gee jou meer veelsydigheid en 1 sekonde besluit op aanvang van die tyd.

Jy kan bc gebruik om die twee opdragte sluit in antwoord skare en kry hoeveel sekondes ellapsed sedert die proses begin:

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

wysig:

Buite verveling terwyl hulle wag vir 'n lang prosesse uit te voer, dit is wat uitgekom na 'n paar minute 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

As jy hierdie sit op jou pad en noem dit soos volg:    sincetime

Dit sal die proses cmdline en sekondes te druk sedert begin. Jy kan dit ook in jou pad:

#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

En as wanneer jy loop:

greptime <pattern>

waar patrone is 'n string of uitgebrei regular expression, sal dit druk al die prosesse wat ooreenstem met hierdie patroon en die sekondes sedert hulle begin het. :)

doen 'n ps -aef. Dit sal jou wys die tyd waarteen die proses begin. Dan met behulp van die date opdrag vind die huidige tyd. Bereken die verskil tussen die twee na die ouderdom van die proses vind.

Ek het iets soortgelyk aan die aanvaarde antwoord maar effens anders, want ek wil aan te pas wat gebaseer is op die proses naam en wat gebaseer is op die slegte proses wat loop vir meer as 100 sekondes

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

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

om die aanvang van die tyd van die proses te kry in sekondes sedert die epog. Vergelyk met die huidige tyd (date +%s) om die huidige ouderdom van die proses te kry.

Die gebruik van PS is die regte manier. Ek het reeds iets soortgelyks voorheen gedoen, maar moenie die bron handig nie. Oor die algemeen - PS het 'n opsie om dit te vertel watter lande om te wys en waardeur te sorteer. Jy kan die uitset te sorteer deur die loop van tyd, grep die proses wat jy wil en dan dood te maak nie.

HTH

In die geval iemand moet hierdie in C, kan jy gebruik readproc.h en 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;
}

afgekom somewhere..thought dit is eenvoudig en nuttig

Jy kan die opdrag direk gebruik in crontab,

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

of kan ons dit skryf as dop script,

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

En noem dit crontab soos so,

* * * * * longprockill.sh

My weergawe van sincetime bo deur @Rafael S. Calsaverini:

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

Dit keer die uitset velde: tydsverloop eerste, magtig, insluitend argumente tweede. Dit word verkies omdat die volle opdrag spasies bevat.

Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top