Esegui il file perl da script PHP, ma non aspettare per l'output su Windows Server

StackOverflow https://stackoverflow.com/questions/4284796

  •  28-09-2019
  •  | 
  •  

Domanda

Nel tentativo di eseguire uno script Perl all'interno di uno script php. Ho avuto questo lavoro utilizzando vari metodi come exec, popen e proc_open ma ho un paio di problemi per andare in giro, che il buon vecchio Google mi isnt dare le risposte a.

Ho bisogno di eseguire lo script .pl (passando una variabile allo script che è un numero) all'interno del file php ma fermare lo script PHP da aspettare fino a quando il .pl ha finito (il .pl rischia di prendere 4 -5 ore per eseguire sul server). Im non aspettarsi alcuna uscita di ritorno dallo script perl (lo script perl registra la sua uscita ad un db MySQL) quindi ho solo bisogno di essere in esecuzione sul server e lasciare che il riporto script php on.

Ci sono alcuni ostacoli per superare la sua esecuzione su un computer Windows in esecuzione apache, php, mysql.

Penso che Ive visto la soluzione per Linux, ma ha bisogno di rimanere sulla macchina Windows.

corrente Im cercando un approccio proc_open utilizzando il seguente codice (il 35 sulla linea proc_open è un id di test ho bisogno di passare allo 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;  
}

Ora, questo codice fa eseguire lo script perl, ma il ciclo while Ive posto dopo di esso (solo per il test) non esegue (ive non aspettò che lo script Perl per finire per vedere se lo fa) come deve essere in attesa del. pl alla fine.

È stato utile?

Soluzione 4

Grazie a tutti coloro che hanno risposto a questa domanda. Dopo molte ricerche e scherzi con diverse soluzioni finalmente ho qualcosa da lavoro e soddisfare le nostre esigenze. La sua ben lungi dall'essere perfetto, ma hey funziona così Im non andare a lamentarmi troppo.

Dal momento che questo sembra essere qualcosa di altre persone vogliono sapere Id pensato Id quota la mia soluzione.

  1. Ho scaricato un piccolo programma chiamato Hstart (40kb) da qui: http: //www.ntwind.com/software/utilities/hstart.html

  2. I estratti i file in c: \ windows \ system32.

Il programma hstart ha la possibilità di eseguire file batch senza aprire una finestra di comando. Non funzionerà chiamando direttamente il file .pl così ho dovuto creare un .bat per chiamare il .pl come segue.

  1. creato un file .bat stessa directory come il mio file .pl che fondamentalmente ha chiamato lo script perl utilizzando Perl installato in locale e passando una variabile. Come esposizione qui:

    perl script.pl% 1

  2. Nel mio script PHP ho usato il seguente comando per chiamare il mio file Perl.

    $ cmd = 'hstart / NOCONSOLE "run.bat' $ id.. '"> Log.log'; exec ($ cmd);

  3. L'esecuzione del file php cause hstart per aprire con NOCONSOLE a causa del flag impostato, aprire il file Perl con il $ id ho passato come una variabile e inviare tutto l'output della finestra della console nascosta per log.log come specificato con il mio comando. Tutto quello che posso vedere è perl.exe in esecuzione nel mio task manager.

Come ho detto ben lungi dall'essere perfetto, ma funziona.

Altri suggerimenti

Posso vedere 3 opzioni:

  • Usa fork nello script perl a sborsare fuori il lavoro effettivo con il processo padre esistente subito dopo forchetta. Questo potrebbe non funzionare correttamente o affatto su Windows, tuttavia, ma vale la pena provare.

    Si prega di consultare la seguente "fork su Windows" riferimenti:

  • Se PHP può lanciare una richiesta di URL (simile a LWP o wget di Perl), quindi convertire il vostro script Perl in uno script CGI (banale), bastone nella directory CGI di Apache, e chiamare tramite un URL corretto per http://localhost/.... Poi il tempo la richiesta URL via sia qualche timeout PHP Iternal o regolari timeout HTTP nel peggiore dei casi. Nel caso in cui davvero peggiore, fare lo stesso trucco dall'interno del codice Perl dal Perl può sicuramente supportare sia la chiamata URL tramite librerie LWP così come timeout tramite alarm()

  • avere un lancio di pianificazione dello script Perl ogni X minuti. Lo script dovrebbe iniziare con la seguente logica:. if (-e $flag_file) { unlink $flag_file; do_long_work() } else { exit 0; } dove $flag_file è la posizione speciale sul server (C:\temp\myscript_start_perl.txt esempio), e do_long_work() contiene il lavoro effettivo che deve essere fatto

    Poi, quando il PHP script deve dare il via alla script Perl, semplicemente crea un file vuoto di bandiera (lo stesso C:\temp\myscript_start_perl.txt), che sarà notata dallo script Perl prossima volta viene eseguito il programma di pianificazione di esso.

Ci sono due possibilità

  1. Usa "start" del programma. Non sarà in grado di utilizzare i tubi, solo gli argomenti della riga di comando.

  2. Crea un programma Perl sempre in esecuzione (eseguire all'avvio o utilizzando Win32 :: Daemon). Connettersi ad esso utilizzando i socket o http. E 'facile, in quanto vi sono un sacco di server pronti su CPAN

Inoltre, può essere possibile fare questo da un altro programma Perl usando Win32 :: qualche altro modulo CPAN di lavoro o Win32 :: Process o.

Recentemente ho pubblicato un modulo per compiti come questo: Win32 :: distaccato

Aggiungi al tuo script perl e sarà eseguito come demone stesso, permettendo lo script PHP per andare avanti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top