eXma » Diskutieren » Computer und Technik
Startseite - Veranstaltungen - Mitglieder - Suche
Vollständige Version anzeigen: php/bash prozess überwachen
Socres
also ich will mittels php den status eines prozesses anhand der pid herausbekommen...

die pid habe ich

nun wollte ich mittels
CODE

system('kill -0 '.$pid, $rueckgabe);

den status abfragen
dummerweise liefert mir das immer ne 1 zurück, egal ob der prozess läuft oder nicht...

wieso?!?!?!

kennt jemand eventuell noch andere möglichkeiten mittels php zu prüfen ob ein prozess läuft?

achso in meiner umgebung kann ich die meissten kommandos nicht nutzen (ps, pidof) deswegen will ichs mit kill machen...

ich verstehs nich sad.gif

achja und proc_get_status() funzt ja nur mit prozessen die php gestartet hat, also mit proc_open()
seb
Zitat(Socres @ 07 Aug 2009, 13:34)
also ich will mittels php den status eines prozesses anhand der pid herausbekommen...

die pid habe ich

nun wollte ich mittels
CODE

system('kill -0 '.$pid, $rueckgabe);




wenn du die pid hast kannste schauen ob es /proc/$pid gibt

grüße

Seb
andre_ny
und dirty vllt noch

CODE

$ ps -A | grep 10165
 10165 ?        00:00:00 sshd
mmarx
Zitat(Socres @ 07 Aug 2009, 13:34)
wieso?!?!?!
*


Wem gehoert denn der Prozess?
I.I
Der tollste bash befehl ist "lsof". Damit kann man alles machen :-). Und in php nicht "system" benutzen. Das checkt den exit code nicht richtig. Du musst proc_open benutzen. Also PHP startet Kindprozess (lsof oder ps oder kill) und bekommt vom Kindproezss dann den exitstatus zurück den kannst du dann auslesen und je nachdem was du zurück bekommst weißt du ob der andere prozess an ist. Der webserver (wenn das phpskript über den Webserver gestartet werden soll) sollte natürlich zugriffsrechte auf die zu wünschenden bashbefehle haben in dem man ihn entsprechend konfiguriert (also als welcher user er laufen soll und welcher Gruppe er angehört). Ich hab selber schon einmal sowas gebastelt und es hat funktioniert.

Ansonsten gibts noch

http://php.net/manual/en/book.pcntl.php

dann musst du dein php aber umkonfigurieren. http://www.php.net/manual/en/pcntl.installation.php
mmarx
lsof ist genauso ein „bash befehl“ wie kill, naemlich gar nicht. Der korrekte Weg geht auch nicht ueber pcntl, sondern ueber posix_kill, das macht den Syscall direkt und spart sich diesen ganzen Shell-Umweg-Wix. Den Rueckgabewert kriegt man dann mit posix_get_last_error, kill(2) ist dein Freund. Bringen tut das aber auch nichts, weil man fuer alle interessanten Prozesse (naemlich alle die, deren echte UID, die nicht mit den echten oder effektiven UIDs des Webservers laeuft) EPERM bekommt:

CODE
mmarx@korenchkin (1487) ~ % id                                      
uid=1000(mmarx) gid=1000(mmarx) groups=20(dialout),24(cdrom),25(floppy),29(audio),44(video),46(plugdev),109(kvm),1000(mmarx),1001(wheel)
mmarx@korenchkin (1488) ~ % ps -U root | tail -n1                    
29450 ?        00:00:00 logger
mmarx@korenchkin (1489) ~ % strace kill -0 29450 2>&1 | grep '^kill('
kill(29450, SIG_0)                      = -1 EPERM (Operation not permitted)
mmarx@korenchkin (1490) ~ %


Unter Linux koennte man mit capabilities (CAP_KILL) darum kommen, muss man aber schon _tierisch_ bescheurt sein, um so etwas einem Webserver anzuvertrauen. Gleiches gilt fuer Webserver mit Nutzer- oder gar root-Rechten. Wer auf Schmerzen steht (gar nicht mal so abwegig, immerhin geht es um PHP), kann suPHP nehmen.
I.I
Jaja KEIN BASHBEFEHLKLUGSCHEISSMARX (man fürht doch das Programm meistens in der Bash aus oder?) . wenn man einen webserver hat der nur intern erreichbar ist ist das mit den Rechten kein problem. Man muss ja dem Webserver auch nicht gleich Rootrechte geben. Wie gesagt mit der beschriebenen Methode funktionierts.
aktsizr
Ich persönlich finde ja ohnehin, dass ihr alle keine Ahnung habt, aber macht ja nix:
root@flunder:~# /bin/kill
Usage:
kill pid ... Send SIGTERM to every process listed.
kill signal pid ... Send a signal to every process listed.
kill -s signal pid ... Send a signal to every process listed.
kill -l List all signal names.
kill -L List all signal names in a nice table.
kill -l signal Convert between signal numbers and names.
root@flunder:~# kill
kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
root@flunder:~# sh
# kill
kill: 1: Usage: kill [-s sigspec | -signum | -sigspec] [pid | job]... or
kill -l [exitstatus]
#

Asklar?
Polygon
Zitat(I.I @ 08 Aug 2009, 04:25)
(man fürht doch das Programm meistens in der Bash aus oder?)
*

Nein
I.I
Zitat(Polygon @ 08 Aug 2009, 10:20)
Nein
*


du nicht ich schon

@aktsizr was soll das denn? War doch hier nicht gefragt wie kill funktioniert.
Polygon
Zitat(I.I @ 08 Aug 2009, 13:36)
du nicht ich schon
*

Fakt ist, es hat mit der Bash nix zu tun (Deine Getränkekisten "Audi-Kisten" zu nennen weil du die immer mitm Audi holst ist in etwa genauso sinnvoll wie zu sagen "kill ist'n Bash-Programm" weil du es aus immer aus der Bash heraus startest). Mag sein, dass du das klugscheisserisch nennst, weil du nicht zugeben kannst, wenn du falsch liegst, aber das ist eher dein persönliches Problem.
aktsizr
Ich bitte darum zu beobachten, dass es sehrwohl den `bash Befehl' `kill' gibt - nämlich als builtin. Weiterhin gibt es aber auch das ausführbare Programm `/bin/kill'. Und zu allem Überfluss führt system gemäß Manual /bin/sh -c "<cmd>" aus, was bedeutet: Auf Lignix mit Link von /bin/sh auf /bin/bash wird die bash ausgeführt (und somit das builtin). Auf Lignix (wie z.B. bei Ubuntu) wird `sh' (Ubuntu: dash) ausgeführt die eine zur Bourne shell kompatible Variante von /bin/sh ist. dash hat aber, wie man aus meinem posting mit wenig Cleverness entnehmen kann, ebenfalls ein builtin für kill (daher auch das andere Erscheinen der `Usage'). Man kann demnach bei der Verwendung eines standardmäßigen Ubuntu durchaus von einem `dash Befehl' sprechen.

Alles klar?

Im Übrigen ist dieser ganze Thread bereits seit dem posting von `seb' Firlefanz. Es dürfte unter Linux am praktikabelsten sein /proc/<pid>/* zu verwenden.

Ciao Kiddos!
mmarx
Zitat(I.I @ 08 Aug 2009, 04:25)
Jaja KEIN BASHBEFEHLKLUGSCHEISSMARX (man fürht doch das Programm meistens in der Bash aus oder?) .
*


Herzlichen Glueckwunsch, du hast den wichtigsten Teil des Beitrags identifiziert.
phanatos
pgrep?
mmarx
Die Tatsache, dass man kill(2) _direkt_ aufrufen kann, und da nicht erst noch eine Shell starten muss, die das dann erledigt?
aktsizr
kill is schlecht weil: Was wenn dein Prozess abschmiert und ein neuer mit der PID gestartet wird (Man denke an nicht sequentielle pid Vergabe sondern randomisierte (grsec, f/openbsd usw. haben ja solche optionen... vielleicht mittlerweile sogar Linux...). proc is hip weil: Is in Grenzen portabel. Kein Abgefahrener ioctl() Hassle (Gibts bei Linux überhaupt ioctls mit dem man die pids anfordern kann?). cmdline usw. zum Abgleichen ob das wirklich der Prozessname ist den ich will. Vertretbarer overhead.

p.s.: Ich stimme mmarx aber zu: Subshell ist ultralame und keine Option.
mmarx
Zitat(mmarx @ 07 Aug 2009, 19:45)
Bringen tut das aber auch nichts, weil […]*


Ist eventuell nicht deutlich genug geworden, dass man /proc nutzen will.
Socres
Also es ging dann doch recht fix. Daß ich immer ne eins zurück bekommen hab is klar, www-data kann den psozess nat nicht anhalten. Ich habs jetzt per ps gemacht, da brauch ich keine recht beachten. Wenn ich jetzt noch die möglichkeit hätte das ganze komplett per php zu machen ohne dazu den prozess mittels php starten z müssen
mmarx
CODE
file_exists('/proc/'.$pid)
Socres
jau aber das file existiert auch schnell ma obwohl der prozess nich läuft
seb
Zitat(Socres @ 10 Aug 2009, 15:15)
jau aber das file existiert auch schnell ma obwohl der prozess nich läuft
*


bitte wie? maximal kann ein anderer prozess die pid bekommen haben .. aber da hast du etweder ewig gewartet oder wir irre prozesse erzeugt

grüße

Seb
I.I
file_exists:
Die Ergebnisse dieser Funktion werden gecached. Weitere Details erhalten Sie bei clearstatcache().

für file_exists('/proc/'.$pid) muss file_exists doch auch auf /proc/ zugreifen können oder seh ich das falsch? @mmarx

Klar ist das ne einfache elegante variante aber ich frag mich wo das problem ist meine Variante zu benutzen :-).
Stormi
Zitat(mmarx @ 08 Aug 2009, 15:44)
Die Tatsache, dass man kill(2) _direkt_ aufrufen kann, <problem>und da nicht erst noch eine Shell starten muss, die das dann erledigt</problem>?
*

aktsizr
Zitat(I.I @ 10 Aug 2009, 15:30)
file_exists:
Die Ergebnisse dieser Funktion werden gecached. Weitere Details erhalten Sie bei clearstatcache().

für file_exists('/proc/'.$pid) muss file_exists doch auch auf /proc/ zugreifen können oder seh ich das falsch? @mmarx

Klar ist das ne einfache elegante variante aber ich frag mich wo das problem ist meine Variante zu benutzen :-).
*

FYI:
strace -s512 ps ax
[...]
stat64("/proc/15", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
open("/proc/15/stat", O_RDONLY) = 6
read(6, "15 (ata_aux) S 2 0 0 0 -1 2149621824 0 0 0 0 0 0 0 0 15 -5 1 0 54 0 0 4294967295 0 0 0 0 0 0 0 2147483647 0 3222581877 0 0 17 0 0 0 0 0 0\n"..., 1023) = 138
close(6) = 0
open("/proc/15/status", O_RDONLY) = 6
read(6, "Name:\tata_aux\nState:\tS (sleeping)\nTgid:\t15\nPid:\t15\nPPid:\t2\nTracerPid:\t0\nUid:\t0\t0\t0\t0\nGid:\t0\t0\t0\t0\nFDSize:\t32\nGroups:\t\nThreads:\t1\nSigQ:\t0/8187\nSigPnd:\t0000000000000000\nShdPnd:\t0000000000000000\nSigBlk:\t0000000000000000\nSigIgn:\tffffffffffffffff\nSigCgt:\t0000000000000000\nCapInh:\t0000000000000000\nCapPrm:\tffffffffffffffff\nCapEff:\tfffffffffffffeff\nCapBnd:\tffffffffffffffff\nCpus_allowed:\tffffffff,ffffffff\nCpus_allowed_list:\t0-63\nMems_allowed:\t1\nMems_allowed_list:\t0\nvoluntary_ctxt_switches:\t2\nnonvoluntary_ctxt_switches"..., 1023) = 517
close(6) = 0
open("/proc/15/cmdline", O_RDONLY) = 6
read(6, ""..., 2047) = 0
close(6) = 0
write(1, " 15 ? S< 0:00 [ata_aux]\n"..., 37 15 ? S< 0:00 [ata_aux]
) = 37
[...]

lsof nimmt auch /proc. Darüberhinaus macht lsof (sogar im Vergleich zu ps) eine ganze _MENGE_ mehr overhead (ps == 3 (sh, ps, grep) mal fork/execve - sick - aber lsof dürfte noch irrer sein!). file_exists() und /proc/pid/cmdline sind die sinnvollen wie auch deutlich schnelleren und weniger overhead verursachenden Alternativen.

@seb: Wie bereits erwähnt: Randomisierte PID Erzeugung ist durchaus verbreitet.
seb
Zitat(aktsizr @ 10 Aug 2009, 15:43)
@seb: Wie bereits erwähnt: Randomisierte PID Erzeugung ist durchaus verbreitet.
*


kommt auf dein system drauf an .. ja .. dennoch is die wahrscheinlichkeit recht gering die gleich nochma zu treffen ..
aktsizr
Zitat(seb @ 10 Aug 2009, 15:49)
kommt auf dein system drauf an .. ja .. dennoch is die wahrscheinlichkeit recht gering die gleich nochma zu treffen ..
*


"recht gering"...
seb
durchaus .. ja .. sonst vergleichste halt noch cmdline wenn de weisst wie dein prozess heisst
aktsizr
Zitat(seb @ 10 Aug 2009, 15:56)
.. sonst vergleichste halt noch cmdline wenn de weisst wie dein prozess heisst
*


I agree!
I.I
@akt and stormi :-) jaja is ja schon klar ..... mich würde das mit der Shell starten nicht groß stören klar dauert das länger und erzeugt vielleicht overhead aber dafür kann ich bei lsof (oder was auch immer) deutlich mehr Informationen bekommen. Zum Beispiel. Welche Files von welchem prozess geöffnet wurden oder welche Files in Benutzung sind (was man sehr häufig für irgendwelche batches braucht die in bestimmten zeitabständen über einen ordner rennen und darauf aktionen ausführen ... ). Ihr wisst was ich meine. Dafür reicht dann ein /proc/pid nicht mehr.

Außerdem wenn ers mit proc_open macht kann er zum Beispiel falls er die pid nicht hat auch nach dem Namen des prozesses gehen etc. ... Er hat einfach mehr Möglichkeiten. Eventuell brauch ers ja nicht und es reicht ihm so aber wenn mal eine andere Anforderung kommt dann ist er mit der anderen Lösung eben vorbereitet. Wir können ja festhalten das die kleinste gemeinsame Lösung file_exists("/proc/....") ist.
mmarx
Zitat(I.I @ 10 Aug 2009, 17:27)
Dafür reicht dann ein /proc/pid nicht mehr.
*


Das ist falsch, was meinst du eigentlich, wo lsof seine Daten hernimmt?
I.I
ja aber du kannst bei file_exists doch nur prüfen ob der Prozess existiert mehr nicht, das war mein Anliegen.
mmarx
Ja meine Guete, dann muss man halt das file_exists durch readlink ersetzen, und? Die Ausgabe von lsof anstaendig zu parsen ist definitiv nicht einfacher, dafuer auf jeden Fall _deutlich_ mehr Overhead.