Ich habe ein Problem mit einigen zombieartigen Prozessen auf einem bestimmten Server, die von Zeit zu Zeit beendet werden müssen. Wie kann ich am besten diejenigen identifizieren, die länger als eine Stunde oder so laufen?
Antworten
Zu viele Anzeigen?Perl's Proc::ProcessTable wird den Zweck erfüllen: http://search.cpan.org/dist/Proc-ProcessTable/
Sie können es in Debian oder Ubuntu installieren mit sudo apt-get install libproc-processtable-perl
Hier ist ein Einzeiler:
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" } }'
Oder, etwas formatierter, in eine Datei namens 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";
}
}
dann laufen perl process.pl
Dies bietet Ihnen mehr Vielseitigkeit und eine 1-Sekunden-Auflösung bei der Startzeit.
Sie können verwenden bc
um die beiden Befehle in der Antwort von mob zu verbinden und zu erfahren, wie viele Sekunden seit Beginn des Prozesses verstrichen sind:
echo `date +%s` - `stat -t /proc/<pid> | awk '{print $14}'` | bc
bearbeiten:
Aus Langeweile, während ich darauf wartete, dass lange Prozesse ablaufen, kam nach ein paar Minuten Tüftelei das folgende Ergebnis heraus:
#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
Wenn du das auf deinen Weg legst und es so nennst: sincetime
wird die cmd-Zeile des Prozesses und die Sekunden seit dem Start ausgegeben. Sie können dies auch in Ihren Pfad einfügen:
#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
Und dann, wenn Sie laufen:
greptime <pattern>
wobei patterns eine Zeichenkette oder ein erweiterter regulärer Ausdruck ist, werden alle Prozesse, die diesem Muster entsprechen, und die Sekunden seit ihrem Start ausgegeben :)
Ich habe etwas Ähnliches wie die akzeptierte Antwort getan, aber etwas anders, da ich auf der Grundlage des Prozessnamens und des fehlerhaften Prozesses, der länger als 100 Sekunden läuft, einen Abgleich vornehmen möchte
kill $(ps -o pid,bsdtime -p $(pgrep bad_process) | awk '{ if ($RN > 1 && $2 > 100) { print $1; }}')