Ich habe ein PHP-Skript, das ein Shell-Skript aufrufen muss, sich aber überhaupt nicht um die Ausgabe kümmert. Das Shell-Skript führt eine Reihe von SOAP-Aufrufen durch und ist langsam abzuschließen. Daher möchte ich die PHP-Anforderung nicht verlangsamen, während sie auf eine Antwort wartet. Tatsächlich sollte die PHP-Anforderung beendet werden können, ohne den Shell-Prozess zu beenden.
Ich habe in den verschiedenen sah exec()
, shell_exec()
, pcntl_fork()
etc. Funktionen, aber keiner von ihnen scheinen genau zu bieten , was ich will. (Oder wenn doch, ist mir nicht klar, wie.) Irgendwelche Vorschläge?
php
asynchronous
shell
AdamTheHutt
quelle
quelle
nice
undionice
zu verhindern, dass es Ihr System überfordert (z. B./usr/bin/ionice -c3 /usr/bin/nice -n19
)Antworten:
Wenn es "die Ausgabe nicht interessiert", konnte der Exec zum Skript nicht mit dem aufgerufen werden
&
Hintergrund des Prozesses werden?BEARBEITEN - Wenn Sie berücksichtigen, was @ AdamTheHut zu diesem Beitrag kommentiert hat, können Sie dies einem Aufruf hinzufügen an
exec
:Dadurch werden sowohl
stdio
(first>
) als auchstderr
(2>
) zum/dev/null
Hintergrund umgeleitet und ausgeführt.Es gibt andere Möglichkeiten, dasselbe zu tun, aber dies ist am einfachsten zu lesen.
Eine Alternative zur obigen Doppelumleitung:
quelle
&> /dev/null &
, xdebug generiert keine Protokolle, wenn Sie dies verwenden. Überprüfen Sie stackoverflow.com/questions/4883171/…/dev/null
ist die Verwendung im Nachhinein die bessere Praxis, da das Schreiben in geschlossene FDs Fehler verursacht, während Versuche zu lesen oder zu schreiben, um/dev/null
einfach stillschweigend nichts zu tun.Früher habe ich bei dafür, wie es wirklich ist ein unabhängiger Prozess zu starten.
quelle
www-data
) nicht über die zu verwendenden Berechtigungen verfügtat
und Sie diese nicht konfigurieren können, können Sie versuchen,<?php exec('sudo sh -c "echo \"command\" | at now" ');
Wenncommand
enthält Anführungszeichen, siehe Escapeeshellarg , um Kopfschmerzen zu vermeidenecho "sudo command" | at now
www-data
/etc/at.deny
An alle Windows-Benutzer: Ich habe eine gute Möglichkeit gefunden, ein asynchrones PHP-Skript auszuführen (eigentlich funktioniert es mit fast allem).
Es basiert auf den Befehlen popen () und pclose (). Und funktioniert sowohl unter Windows als auch unter Unix.
Originalcode von: http://php.net/manual/en/function.exec.php#86329
quelle
myscript.js
sondern schreibennode myscript.js
. Das heißt: Knoten ist die ausführbare Datei, myscript.js ist das auszuführende Skript. Es gibt einen großen Unterschied zwischen ausführbarer Datei und Skript.php artisan
nur hier setzen Kommentar so dass keine Notwendigkeit , warum es nicht funktionieren mit Befehlen TracingUnter Linux können Sie Folgendes tun:
Dadurch wird der Befehl an der Eingabeaufforderung ausgeführt und anschließend einfach die PID zurückgegeben, die Sie auf> 0 prüfen können, um sicherzustellen, dass sie funktioniert.
Diese Frage ist ähnlich: Hat PHP Threading?
quelle
action=generate var1_id=23 var2_id=35 gen_id=535
Segments). Da OP nach dem Ausführen eines Shell-Skripts gefragt hat, benötigen Sie die PHP-spezifischen Teile nicht. Der endgültige Code wäre:$cmd = 'nohup nice -n 10 /path/to/script.sh > /path/to/log/file.log & printf "%u" $!';
nice
sondern auch zu verwendenionice
.&
führt vorhergehenden Code im Hintergrund aus und wird dannprintf
für die formatierte Ausgabe der$!
Variablen verwendet, die die PID enthältDer PHP-Execute-A-Background-Prozess hat einige gute Vorschläge. Ich finde meine ziemlich gut, aber ich bin voreingenommen :)
quelle
Unter Linux können Sie einen Prozess in einem neuen unabhängigen Thread starten, indem Sie am Ende des Befehls ein kaufmännisches Und anhängen
In Windows können Sie den DOS-Befehl "start" verwenden
quelle
start
Befehl unter Windows, er wird nicht asynchron ausgeführt ... Können Sie die Quelle angeben, von der Sie diese Informationen erhalten haben?/B
Parameter. Ich habe es hier erklärt: stackoverflow.com/a/34612967/1709903Der richtige Weg (!) dazu ist
Fork Forks, Setsid weisen den aktuellen Prozess an, ein Master-Prozess zu werden (kein übergeordnetes Element). Execve weist den aufrufenden Prozess an, durch den aufgerufenen Prozess ersetzt zu werden. damit der Elternteil kündigen kann, ohne das Kind zu beeinträchtigen.
quelle
Ich habe das benutzt ...
(wo
PHP_PATH
ist eine Konstante wiedefine('PHP_PATH', '/opt/bin/php5')
oder ähnlich definiert )Es werden Argumente über die Befehlszeile übergeben. Informationen zum Lesen in PHP finden Sie unter argv .
quelle
Der einzige Weg, den ich fand, der wirklich für mich funktionierte, war:
quelle
shell_exec("/usr/local/sbin/command.sh 2>&1 >/dev/null | at now & disown")
und alles was ich bekomme ist:sh: 1: disown: not found
Ich fand auch Symfony Process Component nützlich dafür.
Sehen Sie, wie es in seinem GitHub-Repo funktioniert .
quelle
proc_*
internen Funktionen basiert .Sie können das PHP-Skript auch als Daemon oder Cronjob ausführen :
#!/usr/bin/php -q
quelle
Verwenden Sie ein benanntes Fifo.
Wenn Sie dann die lange laufende Aufgabe starten möchten, schreiben Sie einfach eine neue Zeile (nicht blockierend in die Triggerdatei).
Solange Ihre Eingabe kleiner als
PIPE_BUF
und eine einzelnewrite()
Operation ist, können Sie Argumente in das FIFO schreiben und sie wie$REPLY
im Skript anzeigen lassen .quelle
Ohne Verwendungswarteschlange können Sie Folgendes verwenden
proc_open()
:quelle