2010-11-26 11 views
1

Je suis en train d'essayer d'exécuter un script Perl depuis un script PHP. J'ai eu ce travail en utilisant diverses méthodes telles que exec, popen et proc_open mais j'ai quelques problèmes pour contourner ce que le bon vieux Google ne me donne pas les réponses.Exécuter le fichier perl à partir du script PHP, mais pas attendre la sortie sur Windows Server

Je dois exécuter le script .pl (en transmettant une variable au script qui est un nombre) à partir du fichier php, mais arrêter le script php d'attendre que le .pl soit terminé (le .pl est susceptible de prendre 4-5 heures pour fonctionner sur le serveur). Je ne m'attends pas à une sortie de retour du script perl (le script perl enregistre sa sortie dans un mysql db) donc j'ai juste besoin qu'il fonctionne sur le serveur et que le script php continue.

Il y a quelques barrières à franchir car elle fonctionne sur des machines Windows exécutant apache, php, mysql.

Je pense que j'ai vu la solution pour Linux, mais il doit rester sur la machine Windows.

courant Im essayant une approche proc_open en utilisant le code suivant (35 sur la ligne proc_open est un identifiant de test, je dois passer au script perl):

$descriptorspec = array(
0 => array("pipe","r"), 
1 => array("pipe","w"), 
2 => array("file","./error.log","a") 
) ; 

proc_close(proc_open('perl perlscript.pl 35', $descriptorspec, $pipes)); 

$i = 0; 
while ($i < 1000) { 
    echo ++$i; 
} 

Maintenant, ce code n'exécute le script perl mais la boucle while placée après elle (juste pour tester) ne s'exécute jamais (je n'ai pas attendu que le script perl finisse pour voir si c'est le cas) car elle doit attendre que le .pl soit fini.

+0

Cela semble fournir la réponse pour Linux, mais quelqu'un peut-il faire la lumière sur Windows? http: // stackoverflow.com/questions/3420949/php-using-proc-open-comme-ça-ne-pas-attendre-pour-le-script-ça-ouvre-court-vers-fin – azzy81

Répondre

0

Merci à tous ceux qui ont répondu à cette question. Après beaucoup de recherches et de déconner avec différentes solutions, j'ai enfin trouvé quelque chose qui fonctionne et qui répond à nos besoins. C'est loin d'être parfait mais bon ça marche donc je ne vais pas trop me plaindre.

Depuis que cela semble être quelque chose que d'autres personnes veulent savoir Id pensé Id partager ma solution.

  1. J'ai téléchargé un petit programme appelé HStart (40kb) d'ici: http://www.ntwind.com/software/utilities/hstart.html

  2. J'extrait les fichiers c: \ windows \ system32.

Le programme hstart a la capacité d'exécuter des fichiers de traitement par lots sans ouvrir une fenêtre de commande. Il ne fonctionnera pas en appelant le fichier .pl directement, donc j'ai dû créer un fichier .bat pour appeler le .pl comme suit.

  1. créé un fichier .bat même répertoire que mon fichier .pl qui essentiellement appelé le script Perl utilisant Perl installé localement et passer une variable. Comme le montre ici:

    perl script.pl% 1

  2. Dans mon script PHP j'ai utilisé la commande suivante pour appeler mon fichier perl.

    $ cmd = 'hstart/NOCONSOLE "run.bat'. $ Id. '"> Log.log'; exec ($ cmd); L'exécution du fichier php provoque l'ouverture de hstart avec noconsole en raison du jeu d'indicateurs, l'ouverture du fichier perl avec l'identifiant $ id que j'ai passé en tant que variable et l'envoi de toutes les sorties de la fenêtre de console cachée à log.log comme spécifié avec ma commande. Tout ce que je peux voir est perl.exe en cours d'exécution dans mon gestionnaire de tâches.

Comme je l'ai dit loin de la perfection mais cela fonctionne.

0

je peux voir 3 options:

  • Utilisez fork dans votre script Perl pour bifurquent le travail réel avec le processus parent existant juste après fourchette. Cela peut ne pas fonctionner correctement ou pas du tout sur Windows, mais vaut la peine d'essayer.

    S'il vous plaît voir les suivantes "fork sur Windows" Références:

  • Si PHP peut lancer une URL demande (similaire à LWP ou wget de Perl), puis convertissez vos scripts Perl t dans un script CGI (trivial), restez dans le répertoire CGI de votre Apache, et appelez-le via une URL appropriée au http://localhost/.... Puis expirez la demande d'URL via un délai d'attente PHP iternal ou un délai d'attente HTTP normal dans le pire des cas. Vraiment dans le pire des cas, faites le même tour depuis le code Perl puisque Perl peut supporter aussi bien l'appel URL via les bibliothèques LWP que le timeout via alarm()

  • Demandez à un planificateur de lancer votre script Perl toutes les X minutes. Le script doit commencer avec la logique suivante: if (-e $flag_file) { unlink $flag_file; do_long_work() } else { exit 0; }$flag_file est l'emplacement spécial sur le serveur (par exemple C:\temp\myscript_start_perl.txt), et do_long_work() contient le travail réel qui doit être fait. Ensuite, lorsque le script PHP doit lancer le script Perl, il crée simplement un fichier d'indicateur vide (le même C:\temp\myscript_start_perl.txt), qui sera remarqué par le script Perl la prochaine fois que le planificateur l'exécutera.

+0

le détachement de fourche ne fonctionnerait pas sur Windows –

+0

@Alexandr - S'il vous plaît voir les liens dans les sous-balles. – DVK

0

Il existe des programmes deux possibilités

  1. Utilisez le "départ". Vous ne serez pas en mesure d'utiliser des tuyaux, uniquement des arguments de ligne de commande.

  2. Créez un programme Perl toujours actif (exécuté au démarrage ou en utilisant Win32 :: Daemon). Connectez-vous à l'aide de sockets ou http. Il est facile, car il y a beaucoup de serveurs prêts sur CPAN

En outre, il peut être possible de le faire à partir d'un autre programme Perl utilisant Win32 :: Job ou Win32 :: Process ou un autre module CPAN.

0

I a récemment publié un module pour des tâches comme ceci: Win32::Detached

Ajoutez à votre script perl et il sera lui-même daemon, permettant à votre script PHP pour passer.