[python] Jak získat název procesu když znám PID procesu

Petr Messner petr.messner na gmail.com
Sobota Březen 10 22:11:23 CET 2012


Ahoj,

> Mimochodem linuxovský příkaz ps -d | grep program.py, který by vyfiltroval
> jen to co hledám, funguje pod linuxem, ale přes subprocess ne.
> Hlásí:  ERROR: Garbage option.

Funguje i přes subprocess, jenže se to musí spustit pomocí shellu -
jedná se totiž o dva programy propojené "rourou", ne o jeden program s
parametry "-d", "|", "grep" a "program.py". Takže v Pythonu se Popen
musí vytvořit s parametrem shell=True, nějak takto:

subprocess.Popen("ps -d | grep program.py", shell=True,
stdout=subprocess.PIPE).communicate()

Ještě lepší bude odfiltrovat řádek se sebou samým, na to se používá
třeba tento trik:

subprocess.Popen("ps -d | grep [p]rogram.py", shell=True,
stdout=subprocess.PIPE).communicate()

Pokud vím, tak ps (alespoň v Linuxu) jen zpracovává obsah adresáře
/proc/, takže jeho činnost lze implementovat i v Pythonu. Viz man 5
proc.

Teď k vašemu problému. Azurit navrhl řešení pomocí flock. To je dobré,
aby se jeden program nespustil vícekrát současně, nebo aby skripty v
/etc/init.d mohly poznat, zda program běží, případně zjistit PID pro
poslání signálu.

Navrhuji ještě jiný způsob (nejlépe zkombinovat s tím flock), a to aby
váš "hlídací skript" check.py sám přímo spouštěl ten program.py. Pokud
je totiž child proces ukončen, rodičovský proces se o tom dozví pomocí
signálu nebo zavoláním wait (v Pythonu os.wait; pomocí os.WNOHANG se
dá zařídit, aby volání os.wait nebylo blokující). Pokud check.py takto
zjistí, že program.py byl ukončen, spustí ho znovu. Případně se může
přidat další logika, třeba když nebyl ukončen, ale neodpovídá do
časového limitu, bude ukončen násilně a spuštěn znovu nebo něco
takového.

Úplně stejně fungují supervizory v daemontools a runit. Zkuste se na
to podívat, možná to dělá přesně to, co potřebujete. Tento článek na
Root.cz vypadá celkem dobře:
http://www.root.cz/clanky/inicializace-aneb-od-initu-k-runitu-2/ Není
třeba hned runitem nebo daemontools nahrazovat standardní init, lze to
použít jen pro hlídání několika konkrétních služeb, v Debianu je to
použito třeba v balíčku git-daemon-run.

Možná ale stojí za úvahu, proč ten program.py takto vůbec
kontrolujete, zda běží nebo neběží. To vám jen tak čas od času spadne,
ukončí se? Pokud se snažíte o vytvoření daemona, děláte to správně?
Není to úplně intuitivní, viz např.
http://stackoverflow.com/a/688448/196206 Naštěstí i toto vyřeší výše
zmíněný runit nebo daemontools.

PM


Další informace o konferenci Python