Exec Problem

Moien

(Das hier wird ein local eingesetzter Server, man kann alle Sicherheitsbedenken getrost über Bord werfen. Es ist Linux. Und es ist ein Beispiel, das kill soll später auf userwunsch möglich sein.)

Ich versuche zu verstehen was folgenden Code davon abhält zu funktionieren:

exec('sh -c "sleep 120; touch /mnt/HD/pid/iwashere" \> /dev/null 2\>&1 & echo $! \> /mnt/HD/pid/pid 2\>&1');
echo "PID: ";
$pidfile = file ("/mnt/HD/pid/pid");
$pid = $pidfile[0];
$pid = trim ($pid);
echo $pid."
";
echo "kill -9 ".$pid;
echo exec('kill -9 ' + $pid);
echo "
kill done";

In der ersten Zeile starte ich eine shell die um 2 Minuten verzögert eine Action ausführen soll. Der Rest der Zeile speichert die PID der shell in einer Datei. Die PID wird wieder einlesen und soll dann per kill -9 abgeschossen werden. Das klappt aber nicht, die Shell läuft fröhlich weiter. Die PID stimmt, auf Console lässt sie sich auch mit kill abschiessen. Beide exec’s sollten als der user laufen.

Was hält php davon ab das kill auszuführen ?

posix_kill funktioniert bestens, aber trotzdem will ich wissen wieso das exec ('kill …nicht funktionert.

Danke

Theoriewarnung
Hi Pumpkin,

ich arbeite eher selten mit Unix/Linux und kann deshalb nur theoretisieren…

exec() führt ein gegebenen Befehl aus, ohne eine Ausgabe zu erzeugen. Die Funktion gibt lediglich die letzte Zeile aus dem Befehlsergebnis zurück.

meiner Meinung nach wartet php noch immer darauf, dass die Rückmeldung des Befehls kommt um dann diesen Ausführen zu können.
Das bedeutet 2 Min warten und vermutlich wird - wenn der Befehl ausgeführt wurde auch noch ein wenig mehr berechnet werden…
Inzwischen darf sich das php script vermutlich auf einen Timeout freuen und die weitere bearbeitung wird schlicht und einfach abgebrochen…

Solche Dinge sind immer etwas knifflig - ist mir auch schon aufgefallen…
Vielleicht kannst Du ja das schliessen des Fensters und die Befehlsausübung direkt per shellscript abarbeiten?

Grüsse
Munich

Hallo pumpkin,

echo exec('kill -9 ’ + $pid);
echo "
kill done";

In der ersten Zeile starte ich eine shell die um 2 Minuten
verzögert eine Action ausführen soll. Der Rest der Zeile
speichert die PID der shell in einer Datei. Die PID wird
wieder einlesen und soll dann per kill -9 abgeschossen werden.

Versuchs doch mal mit ‚exec …‘ statt ‚echo exec …‘,
ode hab ich was falsch verstanden?

Grüße

CMБ

Hallo,

echo exec('kill -9 ’ + $pid);

~> type kill
kill is a shell builtin

/bin/kill gibt es aber auch… versuche mal

echo exec(’/bin/kill -9 ’ + $pid+ ’ 2>&1’);

Alexander

Moien

meiner Meinung nach wartet php noch immer darauf, dass die
Rückmeldung des Befehls kommt um dann diesen Ausführen zu
können.

Das stimmt, exec wartet falls es Ausgaben gibt. Da ich alle Streams umleite (> /LOG 2>&1) kriegt php keine Ausgaben und macht weiter. Man sieht alle Ausgaben und den Rest der Seite sofort. Die Abarbeitung läuft ohne Pause durch.

Vielleicht kannst Du ja das schliessen des Fensters und die
Befehlsausübung direkt per shellscript abarbeiten?

Gleiches Resultat.

Danke, aber das war ein Schuss in den Ofen.

Moien

echo exec('kill -9 ’ + $pid);

~> type kill
kill is a shell builtin

/bin/kill gibt es aber auch… versuche mal

Ich hab exec benutzt weil das eine shell startet. Backticks starten keine. Jedenfalls laut doc…

cu

Gelöst
Moine

Ich hab apache durch thttp ersetzt, dann gings. Fragt mich nicht wieso.

Danke

meiner Meinung nach wartet php noch immer darauf, dass die
Rückmeldung des Befehls kommt um dann diesen Ausführen zu
können.

Das stimmt, exec wartet falls es Ausgaben gibt. Da ich alle
Streams umleite (> /LOG 2>&1) kriegt php keine Ausgaben
und macht weiter. Man sieht alle Ausgaben und den Rest der
Seite sofort. Die Abarbeitung läuft ohne Pause durch.

tatsächlich?

ich war der meinung erst das & am ende schiebt den prozess in den hintergund.
der aufruf:

/bin/foo \>/dev/null 2\>&1

verbirgt zwar allen output, aber der aufurfer wartet trotzdem. erst:

/bin/foo \>/dev/null 2\>&1 &

schiebt den przess in den hintergrund.

Moien

Das stimmt, exec wartet falls es Ausgaben gibt. Da ich alle
Streams umleite (> /LOG 2>&1) kriegt php keine Ausgaben
und macht weiter. Man sieht alle Ausgaben und den Rest der
Seite sofort. Die Abarbeitung läuft ohne Pause durch.

tatsächlich?

OK, da hab ich was vergessen: Alle Streams müssen weg und in Background laufen. Sieht php einen Stream oder kein Backrground-flag ist es Essig.

ich war der meinung erst das & am ende schiebt den prozess in
den hintergund.

mach ich doch:

exec(‚sh -c „sleep 120; touch /mnt/HD/pid/iwashere“ > /dev/null 2>&1 & echo $! > /mnt/HD/pid/pid 2>&1‘);

Ich muss aber beides in einmal exec stecken um die PID der mit sh gestarteten shell rauszubekommen. Und das echo läuft in ein paar ms durch (Was auch gut so ist, ich less die Datei ja später aus).

cu