2010-09-29 8 views
49

Ich habe einen Befehl, den ich ausführen möchte, aber ich möchte nicht, dass PHP sitzen und auf das Ergebnis warten.PHP-Exec-Befehl (oder ähnlich), nicht auf Ergebnis warten

<?php 
echo "Starting Script"; 
exec('run_baby_run'); 
echo "Thanks, Script is running in background"; 
?> 

Ist es möglich, PHP zu haben, nicht auf das Ergebnis warten .. heißt es nur kick off und entlang auf den nächsten Befehl bewegen.

Ich kann nichts finden, und nicht sicher ist es sogar möglich. Das Beste, was ich finden konnte, war jemand, der in einer Minute einen CRON-Job machen würde.

+1

Wenn Sie dies häufig zu tun haben, können Sie auch in einer [Jobqueue, wie Gearman] interessiert sein (http://de2.php.net/manual/en/book.gearman.php). – Gordon

Antwort

38

Sie den Befehl im Hintergrund ausgeführt werden kann, indem ein & am Ende davon Zugabe wie:

exec('run_baby_run &'); 

Aber tun dies allein Ihr Skript hängen, weil:

Wenn ein Programm gestartet mit exec-Funktion, damit es weiter im Hintergrund läuft, muss die Ausgabe des Programms in eine Datei oder einen anderen Ausgabestrom umgeleitet werden. Andernfalls wird PHP hängen bleiben, bis die Ausführung des Programms beendet wird.

So können Sie die Standardausgabe des Befehls in eine Datei umleiten, wenn Sie es später sehen wollen oder zu /dev/null, wenn Sie es entsorgen wollen als:

exec('run_baby_run > /dev/null &'); 
+0

das hat super funktioniert, danke für deine Hilfe. – greg

+0

Danke, mein Herr. Das funktioniert perfekt. –

+0

Stederr wird nicht umgeleitet und wird von einem abstürzenden Webserver getötet. –

80

Es ist immer gut zu check the documentation:

um einen Befehl auszuführen, hat es pHP-Skript nicht hängen, während es läuft, das Programm, das Sie laufen zurück zu pHP nicht ausgegeben muss. Um dies zu tun, umleiten sowohl stdout und stderr zu/dev/null, dann Hintergrund es.

>/dev/null 2>&1 &

Um einen Befehl auszuführen und haben es als einen anderen Prozess erzeugte aus, die nicht abhängig von dem Apache-Thread am Laufen zu halten (wird nicht sterben, wenn jemand die Seite bricht) Lauf dies:

exec('bash -c "exec nohup setsid your_command > /dev/null 2>&1 &"');

+0

Vielen Dank! Es gibt viele "Lösungen", die nicht wirklich funktionieren (Der Haupt-Browser-Thread wartet immer noch). Viele Lösungen erzählen nur vom "&" am Ende, was nicht ausreicht. Das heißt, für mich funktionierte eine einfachere Lösung: exec ('nohup your_command>/dev/null 2> & 1 &') war genug. –

+0

Warum musst du 'stdin' nicht auch nach/dev/null portieren? Wird die Eingabe eines Prozesses, die mit einer Shell verbunden ist, ausreichen, um zu verhindern, dass "nohup" den Kindprozess "verleugnet"? (Sie ändern 'stdin' in dieser Antwort: http://superuser.com/questions/178587/how-do-i-i-tach-a-process-from-terminal-entirely) – NHDaly

+0

auch, warum nennst du beide' nohup' und 'sezid'? Ich kann nicht viele Informationen darüber finden, welcher besser ist oder wie sie anders sind. (Http://stackoverflow.com/questions/10247721/on-writing-a-linux-shell-script-to-safely-detach- programme-from-a-terminal) – NHDaly

0

"exec nohup setsid your_command"

die nohup ermöglicht your_command obwohl der Prozess fortzusetzen, die zuerst kündigen gestartet. Wenn dies der Fall ist, wird das Signal SIGNUP an den Befehl your_command gesendet, wodurch dieser beendet wird (es sei denn, er fängt dieses Signal ab und ignoriert es).

+0

Laut [dieser Antwort] (https://stackoverflow.com/a/284443/819417) muss sich ein Kind anmelden, damit SIGHUP über den Tod seiner Eltern informiert wird. Ein Terminal neigt jedoch dazu, das HUP-Signal beim Beenden zu senden. –

6

Ok, hier ist die letzte endgültige richtige preisgekrönte Antwort ;-)

Diese wget verwendet, ohne zu warten eine URL etwas mitzuteilen.

$command = 'wget -qO- http://test.com/data=data'; 
exec('nohup ' . $command . ' >> /dev/null 2>&1 & echo $!', $pid); 

Dies verwendet ls, um ein Protokoll ohne Warten zu aktualisieren.

$command = 'ls -la > content.log'; 
exec('nohup ' . $command . ' >> /dev/null 2>&1 & echo $!', $pid); 
+3

Ich glaube, Sie vermissen ein '&' Symbol zwischen '2> & 1' und' echo', habe ich Recht? –

+0

Lässt nohup das Kind auch laufen, wenn der Elternteil getötet wird? –

+0

@ santiagoarizti ja, ich habe es behoben, da der Code sonst nicht funktionierte –

Verwandte Themen