J'ai un script PHP qui doit invoquer un script shell mais ne se soucie pas du tout de la sortie. Le script shell effectue un certain nombre d'appels SOAP et est lent à terminer, donc je ne veux pas ralentir la demande PHP pendant qu'il attend une réponse. En fait, la requête PHP devrait pouvoir se terminer sans terminer le processus shell.
Je l' ai regardé dans les différents exec()
, shell_exec()
, pcntl_fork()
, etc. fonctions, mais aucun d'entre eux semblent offrir exactement ce que je veux. (Ou, s'ils le font, je ne sais pas trop comment.) Des suggestions?
php
asynchronous
shell
AdamTheHutt
la source
la source
nice
etionice
d'empêcher le script shell de submerger votre système (par exemple/usr/bin/ionice -c3 /usr/bin/nice -n19
)Réponses:
S'il "ne se soucie pas de la sortie", ne pourrait-on pas appeler l'exec du script avec l'
&
arrière-plan du processus?EDIT - incorporant ce que @ AdamTheHut a commenté à ce post, vous pouvez l'ajouter à un appel à
exec
:Cela redirigera
stdio
(en premier>
) etstderr
(2>
) vers/dev/null
et s'exécutera en arrière-plan.Il existe d'autres façons de faire la même chose, mais c'est la plus simple à lire.
Une alternative à la double redirection ci-dessus:
la source
&> /dev/null &
, xdebug ne générera pas de journaux si vous l'utilisez. Vérifiez stackoverflow.com/questions/4883171/…/dev/null
est la meilleure pratique, car l'écriture sur des FD fermés provoque des erreurs, tandis que les tentatives de lecture ou d'écriture pour/dev/null
ne rien faire en silence.Je à pour cela, car il commence vraiment à un processus indépendant.
la source
www-data
) n'a pas les autorisations à utiliserat
et que vous ne pouvez pas le configurer, vous pouvez essayer d'utiliser<?php exec('sudo sh -c "echo \"command\" | at now" ');
Sicommand
contient des guillemets, voir escapeshellarg pour vous éviter des maux de têteecho "sudo command" | at now
et commenterwww-data
en/etc/at.deny
Pour tous les utilisateurs de Windows: j'ai trouvé un bon moyen d'exécuter un script PHP asynchrone (en fait, cela fonctionne avec presque tout).
Il est basé sur les commandes popen () et pclose (). Et fonctionne bien à la fois sur Windows et Unix.
Code d'origine de: http://php.net/manual/en/function.exec.php#86329
la source
myscript.js
mais à la place, vous écrireznode myscript.js
. C'est-à-dire: node est l'exécutable, myscript.js est, enfin, le script à exécuter. Il y a une énorme différence entre l'exécutable et le script.php artisan
mettez simplement un commentaire ici, donc pas besoin de savoir pourquoi cela ne fonctionnera pas avec les commandesSous Linux, vous pouvez effectuer les opérations suivantes:
Cela exécutera la commande à l'invite de commande, puis renverra simplement le PID, que vous pouvez vérifier pour> 0 pour vous assurer qu'il fonctionne.
Cette question est similaire: PHP a-t-il du filetage?
la source
action=generate var1_id=23 var2_id=35 gen_id=535
segment). De plus, puisque OP a demandé l'exécution d'un script shell, vous n'avez pas besoin des parties spécifiques à PHP. Le code final serait:$cmd = 'nohup nice -n 10 /path/to/script.sh > /path/to/log/file.log & printf "%u" $!';
nice
mais aussiionice
.&
exécute le code précédent en arrière-plan, puisprintf
est utilisé pour la sortie formatée de la$!
variable qui contient le PIDphp-execute-a-background-process a de bonnes suggestions. Je pense que le mien est assez bon, mais je suis partial :)
la source
Sous Linux, vous pouvez démarrer un processus dans un nouveau thread indépendant en ajoutant une esperluette à la fin de la commande
Sous Windows, vous pouvez utiliser la commande DOS "start"
la source
start
Commande testée sur Windows, elle ne s'exécute pas de manière asynchrone ... Pourriez-vous inclure la source d'où vous avez obtenu ces informations?/B
paramètre. Je l'ai expliqué ici: stackoverflow.com/a/34612967/1709903la bonne façon (!) de le faire est de
fork forks, setsid indique au processus en cours de devenir maître (pas de parent), execve indique au processus appelant d'être remplacé par celui appelé. afin que le parent puisse arrêter sans affecter l'enfant.
la source
J'ai utilisé ça ...
(où
PHP_PATH
est un const défini commedefine('PHP_PATH', '/opt/bin/php5')
similaire ou similaire)Il passe des arguments via la ligne de commande. Pour les lire en PHP, voir argv .
la source
La seule façon dont j'ai trouvé que cela fonctionnait vraiment pour moi était:
la source
shell_exec("/usr/local/sbin/command.sh 2>&1 >/dev/null | at now & disown")
et tout ce que je reçois est:sh: 1: disown: not found
J'ai également trouvé Symfony Process Component utile pour cela.
Découvrez comment cela fonctionne dans son référentiel GitHub .
la source
proc_*
des fonctions internes.Vous pouvez également exécuter le script PHP en tant que démon ou cronjob :
#!/usr/bin/php -q
la source
Utilisez un fifo nommé.
Ensuite, chaque fois que vous souhaitez démarrer la tâche longue, écrivez simplement une nouvelle ligne (non bloquante dans le fichier déclencheur.
Tant que votre entrée est inférieure à
PIPE_BUF
et qu'il s'agit d'une seulewrite()
opération, vous pouvez écrire des arguments dans le fifo et les faire apparaître comme$REPLY
dans le script.la source
sans utiliser la file d'attente, vous pouvez utiliser
proc_open()
comme ceci:la source