Heute habe ich mich (unter anderem) mit einem Problem beschäftigt das auf den ersten Blick trivial aussieht. Ich zumindest habe bislang keine Lösung gefunden die mir wirklich gefällt. Mal sehen ob was dabei rauskommt wenn ich das hier ‚crowdsource’…
Aufgabenstellung: Zähle, wie viele Prozesse eines bestimmten Programmes schon länger als 30 Minuten laufen.
Klingt einfach, oder?
Die Ausgaben von ps zu parsen erscheint mir dabei aber zu fehleranfällig. Da müsste man zu viel berücksichtigen: Prozesse die vielleicht länger als einen Tag laufen, Prozesse die über Mitternacht gelaufen sind… ich habe nicht getestet wie es aussieht wenn man an der Zeitzone rumspielt… Nein, das kann nicht der richtige Ansatz sein.
Meine erste echte Lösung sieht zwar hässlich originell aus, funktionierte aber im Test (zu Demozwecken suche ich mal nach meinem Firefox):
echo | killall -i --older-than 30m firefox 2> /dev/null | tr -cd '?' | wc -c
Mit -i ist killall ‚interaktiv‘, fragt also zu jedem gefundenen Prozess freundlich nach ob es zuschlagen soll. Mit dem reingepipten echo beantwortet es sich diese Frage immer negativ. Der Rest der Zeile zählt im Prinzip wie oft killall gefragt hat ob es töten soll.
Blöd ist, dass die auf einem etwas älteren RHEL laufen soll. Anders als bei Ubuntu kennt killall da die Option –older-than noch nicht.
Der zweite Lösungsansatz funktioniert leider nur auf den ersten Blick, dafür aber auch auf dem alten Red Hat:
find /proc/[0-9]* -maxdepth 1 -name status -mmin +30 | xargs egrep "^Name:\sfirefox$" | wc -l
Ich suche also alle Prozesse die schon länger als 30 Minuten laufen, und suche in deren status-Datei nach dem Namen meines Prozesses. Die Ergebnisse werden dann wieder gezählt. Alternativ könnte man statt in der status- auch in der cmdline-Datei suchen, in meinem echten Einsatz übersehe ich damit dann auch Zombies (die werden separat betrachtet). Leider funktioniert dieser Ansatz nicht wirklich zuverlässig. Es sieht so aus als ob der Kernel den Dateien im Proc-Verzeichnis bisweilen einen neuen Timestamp gibt — obwohl der Prozess nicht gestartet oder beendet wurde. Ein Schuss in den Ofen, also.
Wie macht man sowas? Ich meine, wenn man eine zuverlässige Lösung mit Bordmitteln haben will? Gibt es da ein passendes Tool das ich noch nicht kenne? Oder hilfreiche Optionen für gängige Tools? Wenn ich die Suchmaschine meiner Wahl frage finde ich eine Menge Lösungen, aber die sind entweder auch wackelig, oder sie bestehen darauf direkt alles zu töten…