2010-09-29 15 views
49

J'ai une commande que je veux lancer, mais je ne veux pas que PHP s'assoie et attende le résultat.Commande php exec (ou similaire) pour ne pas attendre le résultat

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

Est-il possible d'avoir PHP sans attendre le résultat .. dire juste un coup de pied au large et se déplacer le long de la commande suivante.

Je ne trouve rien, et je ne sais pas si c'est possible. Le meilleur que j'ai pu trouver était quelqu'un qui faisait un travail CRON pour commencer dans une minute.

+1

Si vous devez le faire souvent, vous pourriez également être intéressé par un [JobQueue, comme Gearman] (http://de2.php.net/manual/en/book.gearman.php). – Gordon

Répondre

38

Vous pouvez exécuter la commande en arrière-plan en ajoutant un & à la fin de celui-ci comme:

exec('run_baby_run &'); 

Mais faire cela seul accrocher votre script parce que:

Si un programme est a commencé avec la fonction exec, afin qu'il continue à tourner en arrière-plan, la sortie du programme doit être redirigée vers un fichier ou un autre flux de sortie. Si vous ne le faites pas, PHP sera bloqué jusqu'à la fin de l'exécution du programme.

Vous pouvez rediriger la sortie standard de la commande dans un fichier, si vous voulez voir plus tard ou /dev/null si vous voulez jeter comme:

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

qui a bien fonctionné, merci pour votre aide. – greg

+0

Merci, monsieur. Cela fonctionne parfaitement. –

+0

Ne redirige pas stderr et est détruit par un serveur Web défaillant. –

80

Il est toujours bon de check the documentation:

pour exécuter une commande ont l'ont pas accrocher votre script php en il fonctionne, le programme que vous exécutez ne doit pas revenir à la sortie php. Pour ce faire, redirige à la fois stdout et stderr vers/dev/null, puis l'arrière-plan.

>/dev/null 2>&1 &

Pour exécuter une commande et ont il pondu REDUCTIONS un autre processus qui ne dépend pas du fil apache pour continuer à fonctionner (ne mourra pas si quelqu'un annule la page) run ceci:

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

+0

Merci beaucoup! Il y a beaucoup de "solutions" qui ne fonctionnent pas réellement (le thread principal du navigateur est toujours en attente). Beaucoup de solutions ne parlent que du "&" à la fin ce qui n'est pas suffisant. Cela dit, pour moi une solution plus simple a fonctionné à: exec ('nohup votre_commande>/dev/null 2> & 1 &') était suffisant. –

+0

Pourquoi n'avez-vous pas besoin de porter aussi 'stdin' sur/dev/null? Une entrée de processus liée à un shell sera-t-elle suffisante pour empêcher 'nohup' de« renier »le processus fils? (Ils changent 'stdin' dans cette réponse: http://superuser.com/questions/178587/how-do-i-detach-a-process-from-terminal-entirely) – NHDaly

+0

aussi, pourquoi appelles-tu' ' nohup' et 'setsid'? Je ne peux pas trouver beaucoup d'informations sur ce qui est mieux ou comment ils sont différents .. (http://stackoverflow.com/questions/10247721/on-writing-a-linux-shell-script-to-safely-detach- programmes-from-a-terminal) – NHDaly

0

"exec nohup setsid your_command"

le nohup permet your_command de continuer même si le processus qui a lancé peut mettre fin à la première. Si c'est le cas, le signal SIGNUP sera envoyé à your_command pour qu'il se termine (à moins qu'il n'attrape ce signal et l'ignore).

+0

Selon [cette réponse] (https://stackoverflow.com/a/284443/819417), un enfant doit s'inscrire à SIGHUP pour être informé du décès de ses parents. Cependant, un terminal tend à envoyer le signal HUP à la sortie. –

6

Ok, voici la réponse primé correcte finale définitive ;-)

Il utilise wget pour notifier une URL de quelque chose sans attendre.

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

Ceci utilise ls pour mettre à jour un journal sans attendre.

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

Je pense qu'il vous manque un symbole '&' entre '2> & 1' et' echo', ai-je raison? –

+0

Nohup garde-t-il également l'enfant en activité si le parent est tué? –

+0

@santiagoarizti oui, je l'ai corrigé car le code ne fonctionnait pas autrement –