62 votes

PHP StdErr après Exec ()

En PHP, j'exécute une commande avec exec (), qui retourne en cas de succès une URL;

 $url = exec('report');
 

Cependant, je veux vérifier si quelque chose ne va pas. Comment pourrais-je lire le flux? Je veux utiliser php: // stderr, mais je ne sais pas comment l'utiliser.

82voto

Pascal MARTIN Points 195780

Si vous souhaitez exécuter une commande, et d'obtenir à la fois stderr et stdout, pas "fusionné", une solution serait probablement d'utiliser proc_open, ce qui offre un grand niveau de contrôle sur la commande qui est exécutée -- y compris un moyen de tuyau stdin/stdout/stderr.


Et en voici un exemple : nous considérons que nous avons ce shell-script, en test.sh, qui écrit à la fois stderr et stdout :

#!/bin/bash

echo 'this is on stdout';
echo 'this is on stdout too';

echo 'this is on stderr' >&2;
echo 'this is on stderr too' >&2;


Maintenant, laissez-nous le code PHP, en temp.php -- d'abord, nous initialisons le i/o descripteurs :

$descriptorspec = array(
   0 => array("pipe", "r"),  // stdin
   1 => array("pipe", "w"),  // stdout
   2 => array("pipe", "w"),  // stderr
);


Et, ensuite, exécutez l' test.sh de commande, à l'aide de ces descripteurs, dans le répertoire courant, et disant: le i/o devrait être de/vers l' $pipes :

$process = proc_open('./test.sh', $descriptorspec, $pipes, dirname(__FILE__), null);


Nous pouvons maintenant lire les deux tuyaux de sortie :

$stdout = stream_get_contents($pipes[1]);
fclose($pipes[1]);

$stderr = stream_get_contents($pipes[2]);
fclose($pipes[2]);


Et, si nous avons sortie le contenu de ces deux variables :

echo "stdout : \n";
var_dump($stdout);

echo "stderr :\n";
var_dump($stderr);


Nous obtenons le résultat suivant lors de l'exécution de l' temp.php script :

$ php ./temp.php
stdout :
string(40) "this is on stdout
this is on stdout too
"
stderr :
string(40) "this is on stderr
this is on stderr too
"


Espérons que cela aide :-)

51voto

Mark Points 49079

Une petite fonction qui pourrait être utile:

 function my_shell_exec($cmd, &$stdout=null, &$stderr=null) {
    $proc = proc_open($cmd,[
        1 => ['pipe','w'],
        2 => ['pipe','w'],
    ],$pipes);
    $stdout = stream_get_contents($pipes[1]);
    fclose($pipes[1]);
    $stderr = stream_get_contents($pipes[2]);
    fclose($pipes[2]);
    return proc_close($proc);
}
 

Le code de sortie est retourné est renvoyé et STDOUT et STDERR sont des paramètres sortants.

6voto

Li-chih Wu Points 548

Une autre façon d’obtenir stdout / stderr.

 $pp_name = "/tmp/pp_test";
@unlink($pp_name);
posix_mkfifo($pp_name, 0777);
$pp = fopen($pp_name, "r+");
stream_set_blocking($pp, FALSE);
exec("wget -O - http://www.youtube.com 2>$pp_name", $r_stdout);
$r_stderr = stream_get_contents($pp);
var_dump($r_stderr);
fclose($pp);
unlink($pp_name);
 

Si vous voulez ignorer stdout et obtenir uniquement stderr, vous pouvez essayer ceci:

 exec("wget -O - http://www.youtube.com 2>&1 >/dev/null", $r_stderr);
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X