2009-07-28 7 views
4

J'invoque la proc_open() et je ne peux pas capturer la sortie du processus écrit au stderr:capture stderr d'un proc_open() sur les fenêtres

$curFolder = getcwd(); 
$procDescriptor = array(2 => array("pipe", "w")); 
$cmd = "MyApp.exe -f optimization.csv"; 
$process = proc_open($cmd, $procDescriptor, $pipes, $curFolder); 

if(is_resource($process) == true) 
{ 
    $procStatus = proc_get_status($process); 

    while($procStatus['running'] === true) 
    { 
    if(!feof($pipes[2])) 
    { 
     $logLine = fgets($pipes[2]); 
     echo("Read >${logLine}<"); 
    } 
    sleep(1); 
    } 
} 

Le programme se bloque sur les fgets(). Si je lance le programme à partir de la ligne de commande, tout fonctionne, c'est-à-dire qu'il y a quelque chose d'écrit dans stderr (et j'ai aussi essayé en utilisant le stdout avec le même résultat). Je cours le manuscrit sur Windows - le même manuscrit sur Linux court doucement.

Répondre

1

De l'proc_open()docs:

<?php 
$descriptorspec = array(
    0 => array("pipe", "r"), // stdin is a pipe that the child will read from 
    1 => array("pipe", "w"), // stdout is a pipe that the child will write to 
    2 => array("file", "/tmp/error-output.txt", "a") // stderr is a file to write to 
); 

$cwd = '/tmp'; 
$env = array('some_option' => 'aeiou'); 

$process = proc_open('php', $descriptorspec, $pipes, $cwd, $env); 

if (is_resource($process)) { 
    // $pipes now looks like this: 
    // 0 => writeable handle connected to child stdin 
    // 1 => readable handle connected to child stdout 
    // Any error output will be appended to /tmp/error-output.txt 

    fwrite($pipes[0], '<?php print_r($_ENV); ?>'); 
    fclose($pipes[0]); 

    echo stream_get_contents($pipes[1]); 
    fclose($pipes[1]); 

    // It is important that you close any pipes before calling 
    // proc_close in order to avoid a deadlock 
    $return_value = proc_close($process); 

    echo "command returned $return_value\n"; 
} 
?> 

Peut-être que votre processus ne signale pas stderr si vous le trouvez vide

+0

Comme je l'ai écrit ci-dessus, mon processus écrit définitivement quelque chose à la sortie et j'ai essayé de capturer les $ pipes [1] et les $ pipes [2] sans résultat. –

0

Je vous recommande d'ajouter également les flux stdin et stdout, même si vous n » t consommer les données; certaines bibliothèques C entrent dans un tizzy si les flux ne sont pas là, et peuvent soit quitter tôt (glibc) ou potentiellement coincer (certaines versions de MS libc).

5

Vous avez une boucle sans fin. $ ProcStatus ['running'] ne changera jamais à moins que vous n'appeliez l'appel à proc_get_status() à l'intérieur de la boucle. PHP n'a pas de propriétés dynamiques comme JavaScript.

I a ajouté la ligne

$procStatus = proc_get_status($process); 

juste après le sommeil() et il fonctionne très bien.

+0

Alors que je pense qu'il a une boucle sans fin, il existe aussi un problème avec les fgets – SeanDowney

Questions connexes